diff --git a/.gitlab-ci/jobs/help_site_notes.yml b/.gitlab-ci/jobs/help_site_notes.yml index 06cc4461f4..e9afcfd89d 100644 --- a/.gitlab-ci/jobs/help_site_notes.yml +++ b/.gitlab-ci/jobs/help_site_notes.yml @@ -12,7 +12,7 @@ help_site_notes: exit 0 fi apt update && apt install -y git curl gpg - curl -L https://gitlab.com/gitlab-org/cli/-/releases/v1.30.0/downloads/glab_1.30.0_Linux_x86_64.deb --output glab.deb + curl -L https://gitlab.com/gitlab-org/cli/-/releases/v1.38.0/downloads/glab_1.38.0_Linux_x86_64.deb --output glab.deb dpkg -i glab.deb cat "$HELP_SITE_GPG_KEY" > "$GPG_KEY_PATH" bash .gitlab-ci/scripts/bin/help_site.sh diff --git a/.gitlab-ci/scripts/bin/help_site.sh b/.gitlab-ci/scripts/bin/help_site.sh index aac44f6a1a..7d980c82ca 100644 --- a/.gitlab-ci/scripts/bin/help_site.sh +++ b/.gitlab-ci/scripts/bin/help_site.sh @@ -14,7 +14,7 @@ GIT_CI_TOKEN_NAME=${GIT_CI_TOKEN_NAME:-gitlab-ci-token} ACCESS_TOKEN_NAME="help-site-bot" HELP_SITE_REPO="gitlab.com/passbolt/passbolt-help.git" RELEASE_NOTES_PATH="../RELEASE_NOTES.md" - +TARGET_MR_BRANCH="develop" function create_release_notes() { title="$(grep name ../config/version.php | awk -F "'" '{print $4}')" @@ -25,7 +25,7 @@ function create_release_notes() { permalink="/releases/$PASSBOLT_FLAVOUR/$(grep name ../config/version.php | awk -F "'" '{print $4}' | tr ' ' '_' | tr '[:upper:]' '[:lower:]')" date="$(date +'%Y-%m-%d')" - cat << EOF >> _releases/"$PASSBOLT_FLAVOUR"/"$CI_COMMIT_TAG".md + cat <>_releases/"$PASSBOLT_FLAVOUR"/"$CI_COMMIT_TAG".md --- title: $title slug: $slug @@ -40,7 +40,7 @@ date: $date --- EOF - cat $RELEASE_NOTES_PATH >> _releases/"$PASSBOLT_FLAVOUR"/"$CI_COMMIT_TAG".md + cat $RELEASE_NOTES_PATH >>_releases/"$PASSBOLT_FLAVOUR"/"$CI_COMMIT_TAG".md } setup_gpg_key "$GPG_KEY_PATH" "$GPG_PASSPHRASE" "$GPG_KEY_GRIP" @@ -55,6 +55,6 @@ git checkout -b release_notes_"$CI_COMMIT_TAG"_"$PASSBOLT_FLAVOUR" git add _releases/"$PASSBOLT_FLAVOUR"/"$CI_COMMIT_TAG".md git commit -m ":robot: Automatically added release notes for version $CI_COMMIT_TAG $PASSBOLT_FLAVOUR" glab auth login --token "$HELPSITE_TOKEN" -mr_url=$(glab mr create -s release_notes_"$CI_COMMIT_TAG"_"$PASSBOLT_FLAVOUR" -b master -d ":robot: Release notes for $CI_COMMIT_TAG $PASSBOLT_FLAVOUR" -t "Release notes for $PASSBOLT_FLAVOUR $CI_COMMIT_TAG" --push --repo "passbolt/passbolt-help" | grep 'https://gitlab.com/passbolt/passbolt-help/-/merge_requests/') +mr_url=$(glab mr create -s release_notes_"$CI_COMMIT_TAG"_"$PASSBOLT_FLAVOUR" -b "$TARGET_MR_BRANCH" -d ":robot: Release notes for $CI_COMMIT_TAG $PASSBOLT_FLAVOUR" -t "Release notes for $PASSBOLT_FLAVOUR $CI_COMMIT_TAG" --push --repo "passbolt/passbolt-help" | grep 'https://gitlab.com/passbolt/passbolt-help/-/merge_requests/') cd - bash .gitlab-ci/scripts/bin/slack-status-messages.sh ":notebook: New helpsite release notes created for $CI_COMMIT_TAG $PASSBOLT_FLAVOUR" "$mr_url" diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fb8747696..55412183d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,79 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [4.7.0] - 2024-04-30 +### Added +- PB-30330 Add HTTP HEAD method support to /healthcheck/status.json to support more uptime monitoring tools (GITHUB #507) +- PB-26156 As an administrator I can configure SMTP to use TLS with a self-signed cert on my mail server (GITHUB #498) + +### Security +- PB-30255 As an authenticated user I cannot access to the healthcheck endpoint when debug is on + +### Fixed +- PB-30379 As an authenticating user I should not get a 500 if the gpg_auth is not an array +- PB-32889 As an administrator I should not get an exception when running core healthcheck and the host cannot be resolved +- PB-32928 As user I should see the accurate URL in the email footer when passbolt runs on multiple instances +- PB-32566 As a user setting up my account I should not get an unexpected 500 +- PB-32903 Fix deprecation error on password expiry settings validation + +### Maintenance +- PB-29983 Refactor health check code domain for better maintenance +- PB-30394 Moves code in ActionLogsModelListener into a dedicated service +- PB-32881 Disable by default all plugins in integration tests +- PB-32978 Use dependency proxy to reduce docker pull limit +- PB-22605 Refactor ShareSearchControllerTest, SecretViewControllerTest and GroupsDeleteControllerTest with fixture factories +- PB-32594 Add tests for SecretCreateService + +## [4.7.0-rc.1] - 2024-04-26 +### Added +- PB-30330 Add HTTP HEAD method support to /healthcheck/status.json to support more uptime monitoring tools (GITHUB #507) +- PB-26156 As an administrator I can configure SMTP to use TLS with a self-signed cert on my mail server (GITHUB #498) + +### Security +- PB-30255 As an authenticated user I cannot access to the healthcheck endpoint when debug is on + +### Fixed +- PB-30379 As an authenticating user I should not get a 500 if the gpg_auth is not an array +- PB-32889 As an administrator I should not get an exception when running core healthcheck and the host cannot be resolved +- PB-32928 As user I should see the accurate URL in the email footer when passbolt runs on multiple instances +- PB-32566 As a user setting up my account I should not get an unexpected 500 +- PB-32903 Fix deprecation error on password expiry settings validation + +### Maintenance +- PB-29983 Refactor health check code domain for better maintenance +- PB-30394 Moves code in ActionLogsModelListener into a dedicated service +- PB-32881 Disable by default all plugins in integration tests +- PB-32978 Use dependency proxy to reduce docker pull limit +- PB-22605 Refactor ShareSearchControllerTest, SecretViewControllerTest and GroupsDeleteControllerTest with fixture factories +- PB-32594 Add tests for SecretCreateService + +## [4.7.0-test.2] - 2024-04-26 +### Fixed +- PB-33084 New release with fixed release pipes + +## [4.7.0-test.1] - 2024-04-24 +### Added +- PB-30330 Add HTTP HEAD method support to /healthcheck/status.json to support more uptime monitoring tools (GITHUB #507) +- PB-26156 As an administrator I can configure SMTP to use TLS with a self-signed cert on my mail server (GITHUB #498) + +### Security +- PB-30255 As an authenticated user I cannot access to the healthcheck endpoint when debug is on + +### Fixed +- PB-30379 As an authenticating user I should not get a 500 if the gpg_auth is not an array +- PB-32889 As an administrator I should not get an exception when running core healthcheck and the host cannot be resolved +- PB-32928 As user I should see the accurate URL in the email footer when passbolt runs on multiple instances +- PB-32566 As a user setting up my account I should not get an unexpected 500 +- PB-32903 Fix deprecation error on password expiry settings validation + +### Maintenance +- PB-29983 Refactor health check code domain for better maintenance +- PB-30394 Moves code in ActionLogsModelListener into a dedicated service +- PB-32881 Disable by default all plugins in integration tests +- PB-32978 Use dependency proxy to reduce docker pull limit +- PB-22605 Refactor ShareSearchControllerTest, SecretViewControllerTest and GroupsDeleteControllerTest with fixture factories +- PB-32594 Add tests for SecretCreateService + ## [4.6.2] - 2024-04-11 ### Security - PB-32932 Fix error template title diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0c426f8452..a90e22641d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,9 +1,28 @@ -Release song: https://youtu.be/3WOZwwRH6XU?si=jvTiezg7eEEpEh-S +Release song: https://youtu.be/3L4YrGaR8E4 -Passbolt is pleased to announce the immediate availability of version v4.6.2. This version is a targeted security release of both the API and the browser extension focusing on fixing security issues reported by security researchers. +Passbolt Community Edition v4.7 is a maintenance release that resolves multiple issues identified by the community. Furthermore, this release supports the commitment to improving customization options and integration features, making it easier for organizations to tailor the system to their specific needs. -We would like to express our appreciation to the community for their assistance in making Passbolt more secure. Further details about the issues will be shared in a separate communication. +A key enhancement in this release is the ability to use custom SSL certificates for SMTP server connections. This long-awaited feature is particularly beneficial for organizations operating in air-gapped environments or those using their own root CAs, enabling passbolt to more securely integrate with internal tools. + +## [4.7.0] - 2024-04-30 +### Added +- PB-30330 Add HTTP HEAD method support to /healthcheck/status.json to support more uptime monitoring tools (GITHUB #507) +- PB-26156 As an administrator I can configure SMTP to use TLS with a self-signed cert on my mail server (GITHUB #498) -## [4.6.2] - 2024-04-11 ### Security -- PB-32932 Fix error template title +- PB-30255 As an authenticated user I cannot access to the healthcheck endpoint when debug is on + +### Fixed +- PB-30379 As an authenticating user I should not get a 500 if the gpg_auth is not an array +- PB-32889 As an administrator I should not get an exception when running core healthcheck and the host cannot be resolved +- PB-32928 As user I should see the accurate URL in the email footer when passbolt runs on multiple instances +- PB-32566 As a user setting up my account I should not get an unexpected 500 +- PB-32903 Fix deprecation error on password expiry settings validation + +### Maintenance +- PB-29983 Refactor health check code domain for better maintenance +- PB-30394 Moves code in ActionLogsModelListener into a dedicated service +- PB-32881 Disable by default all plugins in integration tests +- PB-32978 Use dependency proxy to reduce docker pull limit +- PB-22605 Refactor ShareSearchControllerTest, SecretViewControllerTest and GroupsDeleteControllerTest with fixture factories +- PB-32594 Add tests for SecretCreateService diff --git a/config/default.php b/config/default.php index 9cfe1a6164..4eb150cc84 100644 --- a/config/default.php +++ b/config/default.php @@ -289,7 +289,13 @@ ], 'smtpSettings' => [ // A typo is here covered for backward compatibility - 'enabled' => filter_var(env('PASSBOLT_PLUGINS_SMTP_SETTINGS_ENABLED', env('PASSBOLT_PLUGINS_SMTP_SETTINGS', true)), FILTER_VALIDATE_BOOLEAN) + 'enabled' => filter_var(env('PASSBOLT_PLUGINS_SMTP_SETTINGS_ENABLED', env('PASSBOLT_PLUGINS_SMTP_SETTINGS', true)), FILTER_VALIDATE_BOOLEAN), + 'security' => [ + 'sslVerifyPeer' => filter_var(env('PASSBOLT_PLUGINS_SMTP_SETTINGS_SECURITY_SSL_VERIFY_PEER', true), FILTER_VALIDATE_BOOLEAN), + 'sslVerifyPeerName' => filter_var(env('PASSBOLT_PLUGINS_SMTP_SETTINGS_SECURITY_SSL_VERIFY_PEER_NAME', true), FILTER_VALIDATE_BOOLEAN), + 'sslAllowSelfSigned' => filter_var(env('PASSBOLT_PLUGINS_SMTP_SETTINGS_SECURITY_SSL_ALLOW_SELF_SIGNED', false), FILTER_VALIDATE_BOOLEAN), + 'sslCafile' => env('PASSBOLT_PLUGINS_SMTP_SETTINGS_SECURITY_SSL_CAFILE', null), + ], ], 'selfRegistration' => [ 'enabled' => filter_var(env('PASSBOLT_PLUGINS_SELF_REGISTRATION_ENABLED', true), FILTER_VALIDATE_BOOLEAN) diff --git a/config/routes.php b/config/routes.php index f335a669e2..a2b9832a41 100644 --- a/config/routes.php +++ b/config/routes.php @@ -164,7 +164,7 @@ $routes->setExtensions(['json']); $routes->connect('/status', ['prefix' => 'Healthcheck', 'controller' => 'HealthcheckStatus', 'action' => 'status']) - ->setMethods(['GET']); + ->setMethods(['GET', 'HEAD']); $routes->connect('/', ['prefix' => 'Healthcheck', 'controller' => 'HealthcheckIndex', 'action' => 'index']) ->setMethods(['GET']); diff --git a/config/version.php b/config/version.php index 95732904a4..dd50e3a4e3 100644 --- a/config/version.php +++ b/config/version.php @@ -1,8 +1,8 @@ [ - 'version' => '4.6.2', - 'name' => 'One Nation Under A Groove', + 'version' => '4.7.0', + 'name' => 'Bulls On Parade', ], 'php' => [ 'minVersion' => '7.4', diff --git a/package-lock.json b/package-lock.json index a8076de1bb..36e5136b9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "passbolt_api", - "version": "3.9.0", + "version": "4.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "passbolt_api", - "version": "3.9.0", + "version": "4.7.0", "license": "AGPL-3.0", "devDependencies": { "babel-polyfill": "^6.26.0", @@ -16,7 +16,7 @@ "jquery": "^3.5.1", "lockfile-lint": "^4.12.1", "openpgp": "5.2.1", - "passbolt-styleguide": "^4.6.1" + "passbolt-styleguide": "^4.7.0" }, "engines": { "node": ">=16.14.0", @@ -177,101 +177,6 @@ "node": ">= 8" } }, - "node_modules/@testing-library/dom": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", - "integrity": "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@testing-library/dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "dev": true - }, "node_modules/@yarnpkg/parsers": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0.tgz", @@ -318,15 +223,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/aria-query": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", - "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, "node_modules/array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", @@ -686,12 +582,6 @@ "integrity": "sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==", "dev": true }, - "node_modules/dom-accessibility-api": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", - "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", - "dev": true - }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -2000,15 +1890,6 @@ "node": ">=12" } }, - "node_modules/lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", - "dev": true, - "bin": { - "lz-string": "bin/bin.js" - } - }, "node_modules/make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -2358,12 +2239,11 @@ } }, "node_modules/passbolt-styleguide": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/passbolt-styleguide/-/passbolt-styleguide-4.6.1.tgz", - "integrity": "sha512-bkSrBF1+MyW3luCFsou0AApzhoY93erRPVKEKk1HFTtYzPDRxXYINKJ8U0Rn7Jm+IvQ7HoaryHyhh8qt/iDnWA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/passbolt-styleguide/-/passbolt-styleguide-4.7.0.tgz", + "integrity": "sha512-8myUPLOQIWUoeTqoWJSGjvQKIOzAF4h0nW1fYqNUALMFuBcC7JjIUrpD7qAqp1tOgCKU5SoSoe22GSf4z7xKag==", "dev": true, "dependencies": { - "@testing-library/dom": "^8.11.3", "debounce-promise": "^3.1.2", "grapheme-splitter": "^1.0.4", "html5-qrcode": "^2.3.8", @@ -2513,41 +2393,6 @@ "node": ">=10.13.0" } }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -2702,12 +2547,6 @@ } } }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/react-list": { "version": "0.8.17", "resolved": "https://registry.npmjs.org/react-list/-/react-list-0.8.17.tgz", @@ -3520,79 +3359,6 @@ "fastq": "^1.6.0" } }, - "@testing-library/dom": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", - "integrity": "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "dev": true - }, "@yarnpkg/parsers": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0.tgz", @@ -3630,12 +3396,6 @@ "sprintf-js": "~1.0.2" } }, - "aria-query": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", - "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", - "dev": true - }, "array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", @@ -3938,12 +3698,6 @@ "integrity": "sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==", "dev": true }, - "dom-accessibility-api": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", - "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", - "dev": true - }, "dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -4969,12 +4723,6 @@ "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", "dev": true }, - "lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", - "dev": true - }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -5228,12 +4976,11 @@ "dev": true }, "passbolt-styleguide": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/passbolt-styleguide/-/passbolt-styleguide-4.6.1.tgz", - "integrity": "sha512-bkSrBF1+MyW3luCFsou0AApzhoY93erRPVKEKk1HFTtYzPDRxXYINKJ8U0Rn7Jm+IvQ7HoaryHyhh8qt/iDnWA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/passbolt-styleguide/-/passbolt-styleguide-4.7.0.tgz", + "integrity": "sha512-8myUPLOQIWUoeTqoWJSGjvQKIOzAF4h0nW1fYqNUALMFuBcC7JjIUrpD7qAqp1tOgCKU5SoSoe22GSf4z7xKag==", "dev": true, "requires": { - "@testing-library/dom": "^8.11.3", "debounce-promise": "^3.1.2", "grapheme-splitter": "^1.0.4", "html5-qrcode": "^2.3.8", @@ -5351,31 +5098,6 @@ "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", "dev": true }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -5482,12 +5204,6 @@ "html-parse-stringify": "^3.0.1" } }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "react-list": { "version": "0.8.17", "resolved": "https://registry.npmjs.org/react-list/-/react-list-0.8.17.tgz", diff --git a/package.json b/package.json index 9e72fc5a46..4dd025912c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "passbolt_api", - "version": "3.9.0", + "version": "4.7.0", "description": "The backend application for the open source password manager for teams", "repository": { "url": "https://github.com/passbolt/passbolt_api" @@ -24,7 +24,7 @@ "jquery": "^3.5.1", "lockfile-lint": "^4.12.1", "openpgp": "5.2.1", - "passbolt-styleguide": "^4.6.1" + "passbolt-styleguide": "^4.7.0" }, "scripts": { "lint": "npm run lint:lockfile", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 2954c1efca..b64a901ae3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -189,8 +189,3 @@ parameters: message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 1 path: src/Service/Resources/ResourcesAddService.php - - - - message: "#^Caught class Cake\\\\Database\\\\Exception not found\\.$#" - count: 2 - path: src/Utility/Healthchecks/DatabaseHealthchecks.php diff --git a/plugins/PassboltCe/EmailDigest/src/Service/SendEmailBatchService.php b/plugins/PassboltCe/EmailDigest/src/Service/SendEmailBatchService.php index 1b1bccff73..05216b5fcf 100644 --- a/plugins/PassboltCe/EmailDigest/src/Service/SendEmailBatchService.php +++ b/plugins/PassboltCe/EmailDigest/src/Service/SendEmailBatchService.php @@ -71,8 +71,6 @@ public function sendNextEmailsBatch(array $emailQueues): void */ private function sendDigest(EmailDigestInterface $emailDigest): void { - $emailDigest->addLayoutVar('title', $emailDigest->getSubject()); - $email = $this->mapEmailDigestToMailerEmail(new Mailer('default'), $emailDigest); try { diff --git a/plugins/PassboltCe/EmailDigest/src/Utility/Factory/EmailPreviewFactory.php b/plugins/PassboltCe/EmailDigest/src/Utility/Factory/EmailPreviewFactory.php index 80526befcf..44127ea626 100644 --- a/plugins/PassboltCe/EmailDigest/src/Utility/Factory/EmailPreviewFactory.php +++ b/plugins/PassboltCe/EmailDigest/src/Utility/Factory/EmailPreviewFactory.php @@ -90,7 +90,8 @@ public function buildSingleEmailDigest(Entity $emailQueueEntity): EmailDigest ->addEmailData($emailQueueEntity) ->setSubject($emailQueueEntity->get('subject')) ->setEmailIds([$emailQueueEntity->id]) - ->setEmailRecipient($emailQueueEntity->get('email')); + ->setEmailRecipient($emailQueueEntity->get('email')) + ->setFullBaseUrl($emailQueueEntity->get('template_vars')['body']['fullBaseUrl'] ?? '/'); } /** @@ -103,16 +104,15 @@ public function buildMultipleEmailDigest(Digest $digest): EmailDigest { $subject = $digest->getTemplate()->getTranslatedSubject($digest); - $emailDigest = new EmailDigest(); + $emailDigest = (new EmailDigest()) + ->setSubject($subject) + ->setEmailRecipient($digest->getRecipient()) + ->setEmailIds($digest->getEmailQueueIds()) + ->setFullBaseUrl($digest->getFullBaseUrl()); foreach ($digest->getEmailQueues() as $emailQueueEntity) { - $emailDigest - ->addEmailData($emailQueueEntity) - ->setSubject($subject) - ->setEmailRecipient($emailQueueEntity->get('email')); + $emailDigest->addEmailData($emailQueueEntity); } - $emailDigest->setEmailIds($digest->getEmailQueueIds()); - return $emailDigest; } @@ -131,6 +131,7 @@ public function buildSummaryEmailDigest(Digest $digest): EmailDigest ->addEmailData($digest->getFirstEmailQueue()) ->setEmailIds($digest->getEmailQueueIds()) ->setSubject($subject) + ->setFullBaseUrl($digest->getFullBaseUrl()) ->addLayoutVar(LocaleEmailQueueListener::VIEW_VAR_KEY, $digest->getLocale()) ->setTemplate($template->getDigestTemplate()) ->setEmailRecipient($digest->getRecipient()) @@ -206,7 +207,7 @@ private function configureEmailView( } /** - * Map an instance of EmailDigest to an instance of Email, so it can be send. + * Map an instance of EmailDigest to an instance of Email, so it can be sent. * * @param \Cake\Mailer\Mailer $email An instance of Email * @param \Passbolt\EmailDigest\Utility\Mailer\EmailDigestInterface $emailDigest An instance of EmailDigest diff --git a/plugins/PassboltCe/EmailDigest/src/Utility/Mailer/EmailDigest.php b/plugins/PassboltCe/EmailDigest/src/Utility/Mailer/EmailDigest.php index 5a3d38ae90..0d4502784a 100644 --- a/plugins/PassboltCe/EmailDigest/src/Utility/Mailer/EmailDigest.php +++ b/plugins/PassboltCe/EmailDigest/src/Utility/Mailer/EmailDigest.php @@ -41,6 +41,7 @@ class EmailDigest implements EmailDigestInterface private string $content; private string $recipient; private string $subject; + private string $fullBaseUrl; /** * @var string|null Template to use to compose the email */ @@ -152,6 +153,7 @@ public function getEmailRecipient(): string public function setSubject(string $subject): self { $this->subject = $subject; + $this->addLayoutVar('title', $subject); return $this; } @@ -205,4 +207,23 @@ public function addLayoutVar(string $name, $value): self return $this; } + + /** + * @inheritDoc + */ + public function setFullBaseUrl(string $fullBaseUrl): self + { + $this->fullBaseUrl = $fullBaseUrl; + $this->addLayoutVar('fullBaseUrl', $fullBaseUrl); + + return $this; + } + + /** + * @inheritDoc + */ + public function getFullBaseUrl(): string + { + return $this->fullBaseUrl; + } } diff --git a/plugins/PassboltCe/EmailDigest/src/Utility/Mailer/EmailInterface.php b/plugins/PassboltCe/EmailDigest/src/Utility/Mailer/EmailInterface.php index 78bcafa6c3..62d4ddb60c 100644 --- a/plugins/PassboltCe/EmailDigest/src/Utility/Mailer/EmailInterface.php +++ b/plugins/PassboltCe/EmailDigest/src/Utility/Mailer/EmailInterface.php @@ -100,4 +100,19 @@ public function setEmailRecipient(string $recipient): self; * @return self */ public function setEmailIds(array $emailIds): self; + + /** + * Sets the full base URL for this digest + * + * @param string $fullBaseUrl full base url + * @return self + */ + public function setFullBaseUrl(string $fullBaseUrl): self; + + /** + * Gets the full base URL for this digest + * + * @return string + */ + public function getFullBaseUrl(): string; } diff --git a/plugins/PassboltCe/EmailDigest/tests/TestCase/Command/PreviewCommandTest.php b/plugins/PassboltCe/EmailDigest/tests/TestCase/Command/PreviewCommandTest.php index fffc83d34c..e542d901a3 100644 --- a/plugins/PassboltCe/EmailDigest/tests/TestCase/Command/PreviewCommandTest.php +++ b/plugins/PassboltCe/EmailDigest/tests/TestCase/Command/PreviewCommandTest.php @@ -27,6 +27,7 @@ use Cake\I18n\I18n; use Cake\Mailer\Mailer; use Passbolt\EmailDigest\Command\PreviewCommand; +use Passbolt\EmailDigest\EmailDigestPlugin; use Passbolt\EmailDigest\Test\Factory\EmailQueueFactory; use Passbolt\EmailDigest\Test\Lib\EmailDigestMockTestTrait; use Passbolt\Locale\Test\Lib\DummyTranslationTestTrait; @@ -53,6 +54,7 @@ public function setUp(): void $this->loadRoutes(); $this->setDummyFrenchTranslator(); (new AvatarsConfigurationService())->loadConfiguration(); + $this->enableFeaturePlugin(EmailDigestPlugin::class); } /** @@ -155,6 +157,7 @@ public function testPreviewCommand_ThresholdExceeded(): void ->setRecipient($recipient) ->setTemplate(ResourceCreateEmailRedactor::TEMPLATE) ->setField('template_vars.body.user', $operator) + ->setField('template_vars.locale', 'en-UK') ->persist(); $this->exec('passbolt email_digest preview'); diff --git a/plugins/PassboltCe/EmailDigest/tests/TestCase/Command/SenderCommandTest.php b/plugins/PassboltCe/EmailDigest/tests/TestCase/Command/SenderCommandTest.php index 2afb4ad16d..a13fdcccff 100644 --- a/plugins/PassboltCe/EmailDigest/tests/TestCase/Command/SenderCommandTest.php +++ b/plugins/PassboltCe/EmailDigest/tests/TestCase/Command/SenderCommandTest.php @@ -58,6 +58,7 @@ public function setUp(): void $this->loadRoutes(); $this->setDummyFrenchTranslator(); (new AvatarsConfigurationService())->loadConfiguration(); + $this->enableFeaturePlugin(EmailDigestPlugin::class); } /** @@ -230,6 +231,7 @@ public function testSenderCommandMultipleDigests() ->setRecipient($recipient) ->setTemplate(ResourceCreateEmailRedactor::TEMPLATE) ->setField('template_vars.body.user', $user) + ->setField('template_vars.locale', 'en-UK') ->persist(); EmailQueueFactory::make($nEmailsSent) @@ -237,6 +239,7 @@ public function testSenderCommandMultipleDigests() ->setTemplate(GroupUserAddEmailRedactor::TEMPLATE) ->setField('template_vars.body.admin', $admin) ->setField('template_vars.body.user', $user) + ->setField('template_vars.locale', 'en-UK') ->persist(); // Upgrade priority of this template to ensure that the emails are sent in this order diff --git a/plugins/PassboltCe/EmailDigest/tests/TestCase/Service/SendEmailBatchServiceCreateResourceChangesDigestTest.php b/plugins/PassboltCe/EmailDigest/tests/TestCase/Service/SendEmailBatchServiceCreateResourceChangesDigestTest.php index 6aabcb3d73..81d94078bd 100644 --- a/plugins/PassboltCe/EmailDigest/tests/TestCase/Service/SendEmailBatchServiceCreateResourceChangesDigestTest.php +++ b/plugins/PassboltCe/EmailDigest/tests/TestCase/Service/SendEmailBatchServiceCreateResourceChangesDigestTest.php @@ -24,6 +24,7 @@ use App\Test\Lib\Utility\EmailTestTrait; use Cake\Console\TestSuite\ConsoleIntegrationTestTrait; use Cake\I18n\I18n; +use Passbolt\EmailDigest\EmailDigestPlugin; use Passbolt\EmailDigest\Service\SendEmailBatchService; use Passbolt\EmailDigest\Test\Factory\EmailQueueFactory; use Passbolt\Folders\Test\Factory\ResourceFactory; @@ -45,6 +46,7 @@ public function setUp(): void $this->useCommandRunner(); $this->service = new SendEmailBatchService(); $this->setEmailNotificationsSetting('password.create', true); + $this->enableFeaturePlugin(EmailDigestPlugin::class); } public function tearDown(): void diff --git a/plugins/PassboltCe/EmailDigest/tests/TestCase/Service/SendEmailBatchServiceUnitTest.php b/plugins/PassboltCe/EmailDigest/tests/TestCase/Service/SendEmailBatchServiceUnitTest.php index cbcff9cb59..4fc784c749 100644 --- a/plugins/PassboltCe/EmailDigest/tests/TestCase/Service/SendEmailBatchServiceUnitTest.php +++ b/plugins/PassboltCe/EmailDigest/tests/TestCase/Service/SendEmailBatchServiceUnitTest.php @@ -433,18 +433,19 @@ public function testSendEmailBatchServiceUnitTest_On_Multiple_Emails_Multiple_Op public function testSendEmailBatchServiceUnitTest_On_Multiple_Full_Base_Url() { $recipient = 'test@passbolt.com'; - $subject = 'Some subject'; + $fullBaseUrl1 = 'passbolt.local/orga-1'; + $fullBaseUrl2 = 'passbolt.local/orga-2'; $operator = UserFactory::make()->withAvatarNull()->getEntity(); $emails1 = ResourceDeleteEmailQueueFactory::make(2) ->setRecipient($recipient) ->setOperator($operator) - ->setFullBaseUrl('foo') + ->setFullBaseUrl($fullBaseUrl1) ->getEntities(); $emails2 = ResourceDeleteEmailQueueFactory::make(2) ->setRecipient($recipient) ->setOperator($operator) - ->setFullBaseUrl('bar') + ->setFullBaseUrl($fullBaseUrl2) ->getEntities(); $allEmails = array_merge($emails1, $emails2); @@ -452,5 +453,9 @@ public function testSendEmailBatchServiceUnitTest_On_Multiple_Full_Base_Url() $this->service->sendNextEmailsBatch($allEmails); $this->assertMailCount(2); + $this->assertMailContainsAt(0, $fullBaseUrl1); + $this->assertMailContainsAt(0, $fullBaseUrl1 . '/img/logo/logo.png'); + $this->assertMailContainsAt(1, $fullBaseUrl2); + $this->assertMailContainsAt(1, $fullBaseUrl2 . '/img/logo/logo.png'); } } diff --git a/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsGetControllerTest.php b/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsGetControllerTest.php index 3516462e0b..5e0bd3a070 100644 --- a/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsGetControllerTest.php +++ b/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsGetControllerTest.php @@ -41,8 +41,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); $this->unloadNotificationSettings(); + parent::tearDown(); } /** diff --git a/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsPostControllerTest.php b/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsPostControllerTest.php index 285f712ef6..91acf08d3c 100644 --- a/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsPostControllerTest.php +++ b/plugins/PassboltCe/EmailNotificationSettings/tests/TestCase/Controllers/NotificationOrgSettingsPostControllerTest.php @@ -34,8 +34,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); $this->unloadNotificationSettings(); + parent::tearDown(); } /** diff --git a/plugins/PassboltCe/Folders/tests/Lib/FoldersIntegrationTestCase.php b/plugins/PassboltCe/Folders/tests/Lib/FoldersIntegrationTestCase.php index 2e936cffa6..9d8b772724 100644 --- a/plugins/PassboltCe/Folders/tests/Lib/FoldersIntegrationTestCase.php +++ b/plugins/PassboltCe/Folders/tests/Lib/FoldersIntegrationTestCase.php @@ -25,10 +25,4 @@ public function setUp(): void parent::setUp(); $this->enableFeaturePlugin('Folders'); } - - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('Folders'); - } } diff --git a/plugins/PassboltCe/Folders/tests/Lib/FoldersTestCase.php b/plugins/PassboltCe/Folders/tests/Lib/FoldersTestCase.php index 6f439821e8..3ff6a2ef96 100644 --- a/plugins/PassboltCe/Folders/tests/Lib/FoldersTestCase.php +++ b/plugins/PassboltCe/Folders/tests/Lib/FoldersTestCase.php @@ -31,10 +31,4 @@ public function setUp(): void 'Passbolt/Locale' => [], ]); } - - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('Folders'); - } } diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Controller/Folders/FoldersIndexControllerPaginationTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Controller/Folders/FoldersIndexControllerPaginationTest.php index d911d574fc..b52ad0c0e9 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Controller/Folders/FoldersIndexControllerPaginationTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Controller/Folders/FoldersIndexControllerPaginationTest.php @@ -30,26 +30,6 @@ class FoldersIndexControllerPaginationTest extends FoldersIntegrationTestCase use FoldersRelationsModelTrait; use PaginationTestTrait; - /** - * setUp method - * - * @return void - */ - public function setUp(): void - { - parent::setUp(); - } - - /** - * tearDown method - * - * @return void - */ - public function tearDown(): void - { - parent::tearDown(); - } - public function dataProviderForSortingDirection(): array { return [ diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Controller/Groups/GroupsDeleteControllerTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Controller/Groups/GroupsDeleteControllerTest.php index 7c3776fb76..f8629384c7 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Controller/Groups/GroupsDeleteControllerTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Controller/Groups/GroupsDeleteControllerTest.php @@ -53,16 +53,6 @@ class GroupsDeleteControllerTest extends FoldersIntegrationTestCase UsersFixture::class, ]; - /** - * setUp method - * - * @return void - */ - public function setUp(): void - { - parent::setUp(); - } - public function testFoldersGroupsDeleteSuccess_PersonalFolder() { [$folderA, $g1, $userAId] = $this->insertFixture_PersonalFolder(); diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Controller/Users/UsersDeleteControllerTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Controller/Users/UsersDeleteControllerTest.php index 0ec37dfd27..641ab3da05 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Controller/Users/UsersDeleteControllerTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Controller/Users/UsersDeleteControllerTest.php @@ -51,16 +51,6 @@ class UsersDeleteControllerTest extends FoldersIntegrationTestCase UsersFixture::class, ]; - /** - * setUp method - * - * @return void - */ - public function setUp(): void - { - parent::setUp(); - } - public function testFoldersUsersDeleteSuccess_PersonalFolder() { [$folderA, $userAId] = $this->insertFixture_PersonalFolder(); diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersDeleteServiceTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersDeleteServiceTest.php index 8ef5c47215..10a843ee91 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersDeleteServiceTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersDeleteServiceTest.php @@ -104,8 +104,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); $this->unloadNotificationSettings(); + parent::tearDown(); } /* COMMON & VALIDATION */ diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersShareServiceTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersShareServiceTest.php index c460d323bc..6cb8d31e84 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersShareServiceTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersShareServiceTest.php @@ -94,8 +94,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); $this->unloadNotificationSettings(); + parent::tearDown(); } public function testShareFolderError_FolderNotFound() diff --git a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersUpdateServiceTest.php b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersUpdateServiceTest.php index a3304f4f67..9732dd75a1 100644 --- a/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersUpdateServiceTest.php +++ b/plugins/PassboltCe/Folders/tests/TestCase/Service/Folders/FoldersUpdateServiceTest.php @@ -92,8 +92,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); $this->unloadNotificationSettings(); + parent::tearDown(); } public function testUpdateFolderSuccess_UpdateFolderMeta() diff --git a/plugins/PassboltCe/JwtAuthentication/src/JwtAuthenticationPlugin.php b/plugins/PassboltCe/JwtAuthentication/src/JwtAuthenticationPlugin.php index 2d03cff68a..6fc29bc7b5 100644 --- a/plugins/PassboltCe/JwtAuthentication/src/JwtAuthenticationPlugin.php +++ b/plugins/PassboltCe/JwtAuthentication/src/JwtAuthenticationPlugin.php @@ -17,6 +17,7 @@ namespace Passbolt\JwtAuthentication; use App\Middleware\CsrfProtectionMiddleware; +use App\Service\Healthcheck\HealthcheckServiceCollector; use Authentication\Middleware\AuthenticationMiddleware; use Cake\Core\BasePlugin; use Cake\Core\ContainerInterface; @@ -35,6 +36,8 @@ use Passbolt\JwtAuthentication\Middleware\JwtRouteFilterMiddleware; use Passbolt\JwtAuthentication\Notification\Email\Redactor\JwtAuthenticationEmailRedactorPool; use Passbolt\JwtAuthentication\Service\AccessToken\JwksGetService; +use Passbolt\JwtAuthentication\Service\Healthcheck\DirectoryNotWritableJwtHealthcheck; +use Passbolt\JwtAuthentication\Service\Healthcheck\ValidKeyPairJwtHealthcheck; class JwtAuthenticationPlugin extends BasePlugin { @@ -85,5 +88,12 @@ public function services(ContainerInterface $container): void { $container->add(JwtArmoredChallengeInterface::class, JwtArmoredChallengeService::class); $container->add(JwksGetService::class); + + $container->add(DirectoryNotWritableJwtHealthcheck::class); + $container->add(ValidKeyPairJwtHealthcheck::class); + $container + ->extend(HealthcheckServiceCollector::class) + ->addMethodCall('addService', [DirectoryNotWritableJwtHealthcheck::class]) + ->addMethodCall('addService', [ValidKeyPairJwtHealthcheck::class]); } } diff --git a/plugins/PassboltCe/JwtAuthentication/src/Service/Healthcheck/DirectoryNotWritableJwtHealthcheck.php b/plugins/PassboltCe/JwtAuthentication/src/Service/Healthcheck/DirectoryNotWritableJwtHealthcheck.php new file mode 100644 index 0000000000..03996a7307 --- /dev/null +++ b/plugins/PassboltCe/JwtAuthentication/src/Service/Healthcheck/DirectoryNotWritableJwtHealthcheck.php @@ -0,0 +1,117 @@ +status = !is_writable(JwtAbstractService::JWT_CONFIG_DIR); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_JWT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The {0} directory is not writable.', JwtAbstractService::JWT_CONFIG_DIR); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The {0} directory should not be writable.', JwtAbstractService::JWT_CONFIG_DIR); + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): array + { + return [ + 'You can try: ', + 'sudo chown -Rf root:' . PROCESS_USER . ' ' . JwtAbstractService::JWT_CONFIG_DIR, + 'sudo chmod 750 ' . JwtAbstractService::JWT_CONFIG_DIR, + 'sudo chmod 640 ' . JwtTokenCreateService::JWT_SECRET_KEY_PATH, + 'sudo chmod 640 ' . JwksGetService::PUBLIC_KEY_PATH, + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_JWT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'jwtWritable'; + } +} diff --git a/plugins/PassboltCe/JwtAuthentication/src/Service/Healthcheck/ValidKeyPairJwtHealthcheck.php b/plugins/PassboltCe/JwtAuthentication/src/Service/Healthcheck/ValidKeyPairJwtHealthcheck.php new file mode 100644 index 0000000000..e1a4080153 --- /dev/null +++ b/plugins/PassboltCe/JwtAuthentication/src/Service/Healthcheck/ValidKeyPairJwtHealthcheck.php @@ -0,0 +1,120 @@ +jwtKeyPairService = new JwtKeyPairService(); + try { + $this->jwtKeyPairService->validateKeyPair(); + $this->status = true; + } catch (\Throwable $e) { + // Do nothing + } + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_JWT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('A valid JWT key pair was found.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('A valid JWT key pair is missing.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): array + { + return [ + __('Run the create JWT keys script to create a valid JWT secret and public key pair:'), + 'sudo su -s /bin/bash -c "' . $this->jwtKeyPairService->getCreateJwtKeysCommand() . '" ' . PROCESS_USER, + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_JWT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'keyPairValid'; + } +} diff --git a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Authenticator/GpgJwtAuthenticatorTest.php b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Authenticator/GpgJwtAuthenticatorTest.php index 283a0a0010..966d4c9128 100644 --- a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Authenticator/GpgJwtAuthenticatorTest.php +++ b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Authenticator/GpgJwtAuthenticatorTest.php @@ -18,6 +18,7 @@ use App\Middleware\ContainerInjectorMiddleware; use App\Test\Lib\Utility\Gpg\GpgAdaSetupTrait; +use App\Utility\Application\FeaturePluginAwareTrait; use App\Utility\OpenPGP\OpenPGPBackendFactory; use App\Utility\UuidFactory; use Authentication\Authenticator\Result; @@ -35,9 +36,11 @@ use Passbolt\JwtAuthentication\Authenticator\GpgJwtAuthenticator; use Passbolt\JwtAuthentication\Authenticator\JwtArmoredChallengeInterface; use Passbolt\JwtAuthentication\Authenticator\JwtArmoredChallengeService; +use Passbolt\JwtAuthentication\JwtAuthenticationPlugin; class GpgJwtAuthenticatorTest extends TestCase { + use FeaturePluginAwareTrait; use GpgAdaSetupTrait; use TruncateDirtyTables; @@ -53,6 +56,7 @@ public function setUp(): void OpenPGPBackendFactory::reset(); $this->sut = new GpgJwtAuthenticator(new TokenIdentifier()); EventManager::instance()->setEventList(new EventList()); + $this->enableFeaturePlugin(JwtAuthenticationPlugin::class); } public function testGpgJwtAuthenticatorAuthenticateError_NoData() @@ -60,7 +64,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_NoData() $this->gpgSetup(); $request = new ServerRequest(); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_InvalidUserId() @@ -69,7 +73,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_InvalidUserId() $request = new ServerRequest(); $request = $request->withData('user_id', 'nope'); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_NotFoundUser() @@ -78,7 +82,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_NotFoundUser() $request = new ServerRequest(); $request = $request->withData('user_id', UuidFactory::uuid()); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_IDENTITY_NOT_FOUND); + $this->assertEquals(Result::FAILURE_IDENTITY_NOT_FOUND, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_NoChallenge() @@ -87,7 +91,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_NoChallenge() $request = new ServerRequest(); $request = $request->withData('user_id', UuidFactory::uuid('user.id.ada')); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_NotOpenPGPChallenge() @@ -99,7 +103,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_NotOpenPGPChallenge() $request = $request->withData('challenge', 'nope'); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_WrongSignatureChallenge() @@ -115,7 +119,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_WrongSignatureChallenge $request = $request->withData('challenge', $msg); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_WrongChallengeFormat() @@ -131,7 +135,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_WrongChallengeFormat() $request = $request->withData('challenge', $msg); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_WrongVersion() @@ -153,7 +157,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_WrongVersion() $request = $request->withData('challenge', $msg); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_WrongDomain() @@ -175,7 +179,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_WrongDomain() $request = $request->withData('challenge', $msg); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_ExpiredToken() @@ -197,7 +201,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_ExpiredToken() $request = $request->withData('challenge', $msg); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateError_WrongVerifyToken() @@ -219,7 +223,7 @@ public function testGpgJwtAuthenticatorAuthenticateError_WrongVerifyToken() $request = $request->withData('challenge', $msg); $result = $this->sut->authenticate($request); - $this->assertEquals($result->getStatus(), Result::FAILURE_CREDENTIALS_INVALID); + $this->assertEquals(Result::FAILURE_CREDENTIALS_INVALID, $result->getStatus()); } public function testGpgJwtAuthenticatorAuthenticateSuccess() diff --git a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/CreateAccessTokenCommandTest.php b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/CreateAccessTokenCommandTest.php index bec502a61a..b21d358fad 100644 --- a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/CreateAccessTokenCommandTest.php +++ b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/CreateAccessTokenCommandTest.php @@ -22,6 +22,7 @@ use Cake\Console\TestSuite\ConsoleIntegrationTestTrait; use Cake\Core\Configure; use CakephpTestSuiteLight\Fixture\TruncateDirtyTables; +use Passbolt\JwtAuthentication\JwtAuthenticationPlugin; /** * @uses \Passbolt\JwtAuthentication\Command\CreateAccessTokenCommand @@ -41,13 +42,7 @@ public function setUp(): void { parent::setUp(); $this->useCommandRunner(); - $this->enableFeaturePlugin('JwtAuthentication'); - } - - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('JwtAuthentication'); + $this->enableFeaturePlugin(JwtAuthenticationPlugin::class); } /** diff --git a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/CreateJwtKeysCommandTest.php b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/CreateJwtKeysCommandTest.php index 1577ade727..fb017646ec 100644 --- a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/CreateJwtKeysCommandTest.php +++ b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/CreateJwtKeysCommandTest.php @@ -19,6 +19,7 @@ use App\Test\Lib\AppTestCase; use App\Test\Lib\Utility\PassboltCommandTestTrait; use Cake\Console\TestSuite\ConsoleIntegrationTestTrait; +use Passbolt\JwtAuthentication\JwtAuthenticationPlugin; /** * @uses \Passbolt\JwtAuthentication\Command\CreateJwtKeysCommand @@ -37,13 +38,7 @@ public function setUp(): void { parent::setUp(); $this->useCommandRunner(); - $this->enableFeaturePlugin('JwtAuthentication'); - } - - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('JwtAuthentication'); + $this->enableFeaturePlugin(JwtAuthenticationPlugin::class); } /** diff --git a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/JwtHealthcheckCommandTest.php b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/JwtHealthcheckCommandTest.php new file mode 100644 index 0000000000..ccd25b713c --- /dev/null +++ b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Command/JwtHealthcheckCommandTest.php @@ -0,0 +1,65 @@ +useCommandRunner(); + $this->mockProcessUserService('www-data'); + $this->enableFeaturePlugin(JwtAuthenticationPlugin::class); + } + + public function testHealthcheckCommand_Jwt_Plugin_Disabled() + { + $this->disableFeaturePlugin(JwtAuthenticationPlugin::class); + $this->exec('passbolt healthcheck --jwt'); + $this->assertExitSuccess(); + $this->assertOutputContains('[WARN] The JWT Authentication plugin is disabled.'); + $this->assertOutputContains('[HELP] Set the environment variable PASSBOLT_PLUGINS_JWT_AUTHENTICATION_ENABLED to true'); + $this->assertOutputContains('No error found. Nice one sparky!'); + } + + public function testHealthcheckCommand_Jwt_Valid() + { + $this->exec('passbolt healthcheck --jwt'); + $this->assertExitSuccess(); + $this->assertOutputContains('[PASS] The JWT Authentication plugin is enabled.'); + if (is_writable(JwtAbstractService::JWT_CONFIG_DIR)) { + $this->assertOutputContains('[FAIL] The ' . JwtAbstractService::JWT_CONFIG_DIR . ' directory should not be writable.'); + } else { + $this->assertOutputContains('[PASS] The ' . JwtAbstractService::JWT_CONFIG_DIR . ' directory is not writable.'); + } + $this->assertOutputContains('[PASS] A valid JWT key pair was found.'); + } +} diff --git a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Controller/JwtLoginControllerTest.php b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Controller/JwtLoginControllerTest.php index 9fb4da3578..9a08dc0113 100644 --- a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Controller/JwtLoginControllerTest.php +++ b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Controller/JwtLoginControllerTest.php @@ -31,6 +31,7 @@ use Cake\Routing\Router; use Cake\Validation\Validation; use Passbolt\JwtAuthentication\Authenticator\GpgJwtAuthenticator; +use Passbolt\JwtAuthentication\JwtAuthenticationPlugin; use Passbolt\JwtAuthentication\Test\Utility\JwtAuthenticationIntegrationTestCase; use Passbolt\Log\Test\Lib\Traits\ActionLogsTestTrait; @@ -66,6 +67,7 @@ public function setUp(): void $this->Users = $this->fetchTable('Users'); $this->ActionLogs = $this->fetchTable('Passbolt/Log.ActionLogs'); $this->enableFeaturePlugin('Log'); + $this->enableFeaturePlugin(JwtAuthenticationPlugin::class); RoleFactory::make()->guest()->persist(); EventManager::instance()->setEventList(new EventList()); TypeFactory::map('uuid', UuidType::class); diff --git a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/RefreshToken/RefreshTokenLogoutServiceTest.php b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/RefreshToken/RefreshTokenLogoutServiceTest.php index 6740e1963e..2cfa43ad00 100644 --- a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/RefreshToken/RefreshTokenLogoutServiceTest.php +++ b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/RefreshToken/RefreshTokenLogoutServiceTest.php @@ -53,6 +53,7 @@ public function setUp(): void public function tearDown(): void { + parent::tearDown(); unset($this->service); } diff --git a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/VerifyToken/VerifyTokenCreateServiceTest.php b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/VerifyToken/VerifyTokenCreateServiceTest.php index d9a548d4df..e5387015c5 100644 --- a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/VerifyToken/VerifyTokenCreateServiceTest.php +++ b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/VerifyToken/VerifyTokenCreateServiceTest.php @@ -61,6 +61,7 @@ public function setUp(): void public function tearDown(): void { + parent::tearDown(); unset($this->service); } diff --git a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/VerifyToken/VerifyTokenValidationServiceTest.php b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/VerifyToken/VerifyTokenValidationServiceTest.php index 3498c4e547..226133d9e2 100644 --- a/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/VerifyToken/VerifyTokenValidationServiceTest.php +++ b/plugins/PassboltCe/JwtAuthentication/tests/TestCase/Service/VerifyToken/VerifyTokenValidationServiceTest.php @@ -51,6 +51,7 @@ public function setUp(): void public function tearDown(): void { + parent::tearDown(); unset($this->service); } diff --git a/plugins/PassboltCe/JwtAuthentication/tests/Utility/JwtAuthenticationIntegrationTestCase.php b/plugins/PassboltCe/JwtAuthentication/tests/Utility/JwtAuthenticationIntegrationTestCase.php index 64aa37f3c6..ea2251fb06 100644 --- a/plugins/PassboltCe/JwtAuthentication/tests/Utility/JwtAuthenticationIntegrationTestCase.php +++ b/plugins/PassboltCe/JwtAuthentication/tests/Utility/JwtAuthenticationIntegrationTestCase.php @@ -17,6 +17,7 @@ namespace Passbolt\JwtAuthentication\Test\Utility; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\JwtAuthentication\JwtAuthenticationPlugin; abstract class JwtAuthenticationIntegrationTestCase extends AppIntegrationTestCase { @@ -28,16 +29,7 @@ abstract class JwtAuthenticationIntegrationTestCase extends AppIntegrationTestCa public function setUp(): void { parent::setUp(); - $this->enableFeaturePlugin('JwtAuthentication'); + $this->enableFeaturePlugin(JwtAuthenticationPlugin::class); $this->disableCsrfToken(); } - - /** - * Tear down - */ - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('JwtAuthentication'); - } } diff --git a/plugins/PassboltCe/Locale/tests/TestCase/Controller/AccountLocalesSelectControllerTest.php b/plugins/PassboltCe/Locale/tests/TestCase/Controller/AccountLocalesSelectControllerTest.php index 058022bcb7..de28b7f10a 100644 --- a/plugins/PassboltCe/Locale/tests/TestCase/Controller/AccountLocalesSelectControllerTest.php +++ b/plugins/PassboltCe/Locale/tests/TestCase/Controller/AccountLocalesSelectControllerTest.php @@ -43,8 +43,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); GetOrgLocaleService::clearOrganisationLocale(); + parent::tearDown(); } public function testAccountLocalesSelectAsGuestFails() diff --git a/plugins/PassboltCe/Locale/tests/TestCase/Controller/OrganizationLocalesSelectControllerTest.php b/plugins/PassboltCe/Locale/tests/TestCase/Controller/OrganizationLocalesSelectControllerTest.php index 0a416a638e..3fdc953b5b 100644 --- a/plugins/PassboltCe/Locale/tests/TestCase/Controller/OrganizationLocalesSelectControllerTest.php +++ b/plugins/PassboltCe/Locale/tests/TestCase/Controller/OrganizationLocalesSelectControllerTest.php @@ -42,8 +42,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); GetOrgLocaleService::clearOrganisationLocale(); + parent::tearDown(); } public function testOrganizationLocalesSelectAsGuestFails() diff --git a/plugins/PassboltCe/Locale/tests/TestCase/Event/ValidateLocaleOnBeforeSaveListenerTest.php b/plugins/PassboltCe/Locale/tests/TestCase/Event/ValidateLocaleOnBeforeSaveListenerTest.php index 4780d11c0c..8692161331 100644 --- a/plugins/PassboltCe/Locale/tests/TestCase/Event/ValidateLocaleOnBeforeSaveListenerTest.php +++ b/plugins/PassboltCe/Locale/tests/TestCase/Event/ValidateLocaleOnBeforeSaveListenerTest.php @@ -37,8 +37,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); GetOrgLocaleService::clearOrganisationLocale(); + parent::tearDown(); } public function dataForTestEmailLocaleServiceGetLocale(): array diff --git a/plugins/PassboltCe/Locale/tests/TestCase/Middleware/LocaleMiddlewareTest.php b/plugins/PassboltCe/Locale/tests/TestCase/Middleware/LocaleMiddlewareTest.php index b07169f996..1d83e59b50 100644 --- a/plugins/PassboltCe/Locale/tests/TestCase/Middleware/LocaleMiddlewareTest.php +++ b/plugins/PassboltCe/Locale/tests/TestCase/Middleware/LocaleMiddlewareTest.php @@ -27,8 +27,8 @@ class LocaleMiddlewareTest extends AppIntegrationTestCase { public function tearDown(): void { - parent::tearDown(); I18n::setLocale('en_UK'); + parent::tearDown(); } public function testLocaleMiddlewareUnauthenticatedRequestWithOrgSetting() diff --git a/plugins/PassboltCe/Locale/tests/TestCase/Notification/ResourcesAddAndShareControllerTest.php b/plugins/PassboltCe/Locale/tests/TestCase/Notification/ResourcesAddAndShareControllerTest.php index beae29fcf8..94d36b2709 100644 --- a/plugins/PassboltCe/Locale/tests/TestCase/Notification/ResourcesAddAndShareControllerTest.php +++ b/plugins/PassboltCe/Locale/tests/TestCase/Notification/ResourcesAddAndShareControllerTest.php @@ -38,17 +38,11 @@ public function setUp(): void parent::setUp(); ResourceTypeFactory::make()->default()->persist(); GetOrgLocaleService::clearOrganisationLocale(); - $this->setEmailNotificationsSetting('password.create', true); - } - - public function tearDown(): void - { - parent::tearDown(); - $this->restoreEmailNotificationsSettings(); } public function testResourcesAdd_Should_Send_Email_In_User_Locale() { + $this->setEmailNotificationsSetting('password.create', true); $frenchLocale = 'fr-FR'; $frenchUser = UserFactory::make()->user()->withLocale($frenchLocale)->persist(); diff --git a/plugins/PassboltCe/Locale/tests/TestCase/Service/RequestLocaleParserServiceTest.php b/plugins/PassboltCe/Locale/tests/TestCase/Service/RequestLocaleParserServiceTest.php index 7c3d3b6ac1..e41e6c3a5d 100644 --- a/plugins/PassboltCe/Locale/tests/TestCase/Service/RequestLocaleParserServiceTest.php +++ b/plugins/PassboltCe/Locale/tests/TestCase/Service/RequestLocaleParserServiceTest.php @@ -45,6 +45,7 @@ public function tearDown(): void { GetOrgLocaleService::clearOrganisationLocale(); $this->removeFooSystemLocale(); + parent::tearDown(); } public function dataForTestRequestLocaleParserServiceGetLocale(): array diff --git a/plugins/PassboltCe/Log/src/Events/ActionLogsModelListener.php b/plugins/PassboltCe/Log/src/Events/ActionLogsModelListener.php index 55bba1a31c..10ac718cb9 100644 --- a/plugins/PassboltCe/Log/src/Events/ActionLogsModelListener.php +++ b/plugins/PassboltCe/Log/src/Events/ActionLogsModelListener.php @@ -15,13 +15,13 @@ */ namespace Passbolt\Log\Events; +use Cake\Core\Configure; +use Cake\Event\Event; use Cake\Event\EventListenerInterface; -use Passbolt\Log\Events\Traits\EntitiesHistoryTrait; +use Passbolt\Log\Service\EntitiesHistory\EntitiesHistoryCreateService; class ActionLogsModelListener implements EventListenerInterface { - use EntitiesHistoryTrait; - /** * @inheritDoc */ @@ -39,4 +39,66 @@ public function implementedEvents(): array 'Model.initialize' => 'entityAssociationsInitialize', ]; } + + /** + * Entity associations initialize + * Initialize needed associations for the required core models on the fly. + * Example: we need to associate PermissionsHistory to Permissions in order to track the history. + * + * @param \Cake\Event\Event $event the event + * @return void + */ + public function entityAssociationsInitialize(Event $event) + { + $table = $event->getSubject(); + $modelName = $table->getAlias(); + + if ($modelName == 'Permissions') { + $table->belongsTo('Passbolt/Log.PermissionsHistory', [ + 'foreignKey' => 'foreign_key', + ]); + } + if ($modelName == 'Resources') { + $table->belongsTo('Passbolt/Log.EntitiesHistory', [ + 'foreignKey' => 'foreign_key', + ]); + } + if ($modelName == 'Secrets') { + $table->belongsTo('Passbolt/Log.SecretsHistory', [ + 'foreignKey' => 'foreign_key', + ]); + $table->hasMany('Passbolt/Log.SecretAccesses'); + } + if ($modelName == 'SecretAccesses') { + $table->belongsTo('Passbolt/Log.EntitiesHistory', [ + 'foreignKey' => 'foreign_key', + ]); + } + if (Configure::read('passbolt.plugins.folders.enabled')) { + if ($modelName == 'Folders') { + $table->belongsTo('FoldersHistory', [ + 'className' => 'Passbolt/Folders.FoldersHistory', + 'foreignKey' => 'foreign_key', + ]); + } + if ($modelName == 'FoldersRelations') { + $table->belongsTo('FoldersRelationsHistory', [ + 'className' => 'Passbolt/Folders.FoldersRelationsHistory', + 'foreignKey' => 'foreign_key', + ]); + } + } + } + + /** + * Log entity history. + * + * @param \Cake\Event\Event $event the event + * @return void + */ + public function logEntityHistory(Event $event) + { + $entitiesHistoryService = new EntitiesHistoryCreateService(); + $entitiesHistoryService->logEntityHistory($event); + } } diff --git a/plugins/PassboltCe/Log/src/Events/Traits/EntitiesHistoryTrait.php b/plugins/PassboltCe/Log/src/Service/EntitiesHistory/EntitiesHistoryCreateService.php similarity index 79% rename from plugins/PassboltCe/Log/src/Events/Traits/EntitiesHistoryTrait.php rename to plugins/PassboltCe/Log/src/Service/EntitiesHistory/EntitiesHistoryCreateService.php index 17a688cb01..f0439b99c3 100644 --- a/plugins/PassboltCe/Log/src/Events/Traits/EntitiesHistoryTrait.php +++ b/plugins/PassboltCe/Log/src/Service/EntitiesHistory/EntitiesHistoryCreateService.php @@ -13,16 +13,15 @@ * @license https://opensource.org/licenses/AGPL-3.0 AGPL License * @link https://www.passbolt.com Passbolt(tm) */ -namespace Passbolt\Log\Events\Traits; +namespace Passbolt\Log\Service\EntitiesHistory; use App\Utility\UserAction; -use Cake\Core\Configure; use Cake\Event\Event; use Cake\ORM\Entity; use Cake\ORM\Table; use Passbolt\Log\Model\Entity\EntityHistory; -trait EntitiesHistoryTrait +class EntitiesHistoryCreateService { /** * @var array @@ -166,80 +165,13 @@ trait EntitiesHistoryTrait ], ]; - /** - * Log entity history. - * - * @param \Cake\Event\Event $event the event - * @return void - */ - public function logEntityHistory(Event $event) - { - if ( - $event->getName() == 'Model.afterSave' || - $event->getName() == 'Model.afterDelete' || - $event->getName() == 'Model.afterRead' - ) { - $this->_logEntityHistory($event); - } - } - - /** - * Entity associations initialize - * Initialize needed associations for the required core models on the fly. - * Example: we need to associate PermissionsHistory to Permissions in order to track the history. - * - * @param \Cake\Event\Event $event the event - * @return void - */ - public function entityAssociationsInitialize(Event $event) - { - $table = $event->getSubject(); - $modelName = $table->getAlias(); - - if ($modelName == 'Permissions') { - $table->belongsTo('Passbolt/Log.PermissionsHistory', [ - 'foreignKey' => 'foreign_key', - ]); - } - if ($modelName == 'Resources') { - $table->belongsTo('Passbolt/Log.EntitiesHistory', [ - 'foreignKey' => 'foreign_key', - ]); - } - if ($modelName == 'Secrets') { - $table->belongsTo('Passbolt/Log.SecretsHistory', [ - 'foreignKey' => 'foreign_key', - ]); - $table->hasMany('Passbolt/Log.SecretAccesses'); - } - if ($modelName == 'SecretAccesses') { - $table->belongsTo('Passbolt/Log.EntitiesHistory', [ - 'foreignKey' => 'foreign_key', - ]); - } - if (Configure::read('passbolt.plugins.folders.enabled')) { - if ($modelName == 'Folders') { - $table->belongsTo('FoldersHistory', [ - 'className' => 'Passbolt/Folders.FoldersHistory', - 'foreignKey' => 'foreign_key', - ]); - } - if ($modelName == 'FoldersRelations') { - $table->belongsTo('FoldersRelationsHistory', [ - 'className' => 'Passbolt/Folders.FoldersRelationsHistory', - 'foreignKey' => 'foreign_key', - ]); - } - } - } - /** * Log entity history * * @param \Cake\Event\Event $event event * @return void */ - private function _logEntityHistory(Event $event) + public function logEntityHistory(Event $event) { $table = $event->getSubject(); $modelName = $table->getAlias(); @@ -377,7 +309,7 @@ private function isLogOperationNeeded(Event $event, string $actionName): bool * @param string $actionName action name * @return array|null */ - public function getEntitiesHistoryConfig(string $actionName): ?array + private function getEntitiesHistoryConfig(string $actionName): ?array { if (isset($this->config[$actionName])) { return $this->config[$actionName]; diff --git a/plugins/PassboltCe/Log/tests/Lib/LogIntegrationTestCase.php b/plugins/PassboltCe/Log/tests/Lib/LogIntegrationTestCase.php index 155c3b8450..b241c03d1a 100644 --- a/plugins/PassboltCe/Log/tests/Lib/LogIntegrationTestCase.php +++ b/plugins/PassboltCe/Log/tests/Lib/LogIntegrationTestCase.php @@ -18,7 +18,6 @@ use App\Model\Entity\User; use App\Test\Lib\AppIntegrationTestCase; -use App\Utility\UserAction; use Cake\Core\Configure; use Cake\ORM\TableRegistry; use Passbolt\JwtAuthentication\Test\Utility\JwtAuthTestTrait; @@ -74,9 +73,6 @@ public function setUp(): void parent::setUp(); Configure::write('passbolt.plugins.log.enabled', true); - UserAction::destroy(); - TableRegistry::getTableLocator()->clear(); - $this->Resources = TableRegistry::getTableLocator()->get('Resources'); $this->Permissions = TableRegistry::getTableLocator()->get('Permissions'); $this->Secrets = TableRegistry::getTableLocator()->get('Secrets'); @@ -107,13 +103,6 @@ public function setUp(): void $this->Actions->clearCache(); } - public function tearDown(): void - { - // Remove dynamically added associations - TableRegistry::getTableLocator()->clear(); - $this->disableFeaturePlugin('JwtAuthentication'); - } - public function dataProviderForLoginType(): array { return [[self::SESSION_LOGIN], [self::JWT_LOGIN]]; diff --git a/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersCreateControllerTest.php b/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersCreateControllerTest.php index c6ddc85686..d4c04d8e83 100644 --- a/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersCreateControllerTest.php +++ b/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersCreateControllerTest.php @@ -38,12 +38,6 @@ public function setUp(): void $this->enableFeaturePlugin('mobile'); } - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('mobile'); - } - public function testMobileTransfersCreateController_Success() { $data = [ diff --git a/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersUpdateControllerTest.php b/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersUpdateControllerTest.php index 2e7d18acfb..f4c893233e 100644 --- a/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersUpdateControllerTest.php +++ b/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersUpdateControllerTest.php @@ -47,12 +47,6 @@ public function setUp(): void $this->enableFeaturePlugin('mobile'); } - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('mobile'); - } - public function testMobileTransfersUpdateController_Success() { $user = UserFactory::make()->user()->persist(); diff --git a/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersViewControllerTest.php b/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersViewControllerTest.php index 6ec9d344ed..d128f989b8 100644 --- a/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersViewControllerTest.php +++ b/plugins/PassboltCe/Mobile/tests/TestCase/Controller/Transfers/TransfersViewControllerTest.php @@ -35,12 +35,6 @@ public function setUp(): void $this->enableFeaturePlugin('mobile'); } - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('mobile'); - } - public function testMobileTransfersViewController_Success() { $user = $this->logInAsUser(); diff --git a/plugins/PassboltCe/MultiFactorAuthentication/tests/Lib/MfaIntegrationTestCase.php b/plugins/PassboltCe/MultiFactorAuthentication/tests/Lib/MfaIntegrationTestCase.php index da8a12eb55..0754f24471 100644 --- a/plugins/PassboltCe/MultiFactorAuthentication/tests/Lib/MfaIntegrationTestCase.php +++ b/plugins/PassboltCe/MultiFactorAuthentication/tests/Lib/MfaIntegrationTestCase.php @@ -46,13 +46,6 @@ public function setUp(): void MfaSettings::clear(); } - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('MultiFactorAuthentication'); - $this->disableFeaturePlugin('JwtAuthentication'); - } - /** * @param UserAccessControl $uac UAC * @param string|null $provider provider diff --git a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Controllers/MfaMiddlewareLoginTest.php b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Controllers/MfaMiddlewareLoginTest.php index 63b3f12aa9..3eee28b2ab 100644 --- a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Controllers/MfaMiddlewareLoginTest.php +++ b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Controllers/MfaMiddlewareLoginTest.php @@ -47,12 +47,6 @@ public function setUp(): void $this->enableFeaturePlugin('JwtAuthentication'); } - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin('JwtAuthentication'); - } - /** * Regression test * POST /auth/login with correct data should return 200 even when MFA is required diff --git a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Event/ClearMfaCookieOnSetupAndRecoverTest.php b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Event/ClearMfaCookieOnSetupAndRecoverTest.php index a06ab19b58..0be6dedc3a 100644 --- a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Event/ClearMfaCookieOnSetupAndRecoverTest.php +++ b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Event/ClearMfaCookieOnSetupAndRecoverTest.php @@ -28,6 +28,7 @@ use Passbolt\MultiFactorAuthentication\Event\ClearMfaCookieOnSetupAndRecover; use Passbolt\MultiFactorAuthentication\Test\Lib\MfaIntegrationTestCase; use Passbolt\MultiFactorAuthentication\Utility\MfaVerifiedCookie; +use Passbolt\SelfRegistration\SelfRegistrationPlugin; use Passbolt\SelfRegistration\Test\Lib\SelfRegistrationTestTrait; class ClearMfaCookieOnSetupAndRecoverTest extends MfaIntegrationTestCase @@ -108,6 +109,7 @@ public function testClearMfaCookieOnSetupAndRecover_clearMfaCookieInResponse_Pos */ public function testClearMfaCookieOnSetupAndRecover_UsersRegisterGetSuccess() { + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); $this->setSelfRegistrationSettingsData(); $this->get('/users/register'); $this->assertResponseOk(); @@ -119,6 +121,7 @@ public function testClearMfaCookieOnSetupAndRecover_UsersRegisterGetSuccess() */ public function testClearMfaCookieOnSetupAndRecover_UsersRegisterPostSuccess() { + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); $this->setSelfRegistrationSettingsData(); RoleFactory::make()->user()->persist(); $data = [ diff --git a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Notification/Email/MfaUserSettingsResetEmailRedactorTest.php b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Notification/Email/MfaUserSettingsResetEmailRedactorTest.php index 06bfa32f2c..a7572bc953 100644 --- a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Notification/Email/MfaUserSettingsResetEmailRedactorTest.php +++ b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Notification/Email/MfaUserSettingsResetEmailRedactorTest.php @@ -35,10 +35,9 @@ class MfaUserSettingsResetEmailRedactorTest extends TestCase public function setUp(): void { + parent::setUp(); $this->sut = new MfaUserSettingsResetEmailRedactor(); $this->loadPlugins(['Passbolt/Locale' => []]); - - parent::setUp(); } public function testThatEmailIsSubscribedToEvent() diff --git a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/Duo/MfaDuoVerifyDuoCodeServiceTest.php b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/Duo/MfaDuoVerifyDuoCodeServiceTest.php index ab058db0fa..d07f516fa8 100644 --- a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/Duo/MfaDuoVerifyDuoCodeServiceTest.php +++ b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/Duo/MfaDuoVerifyDuoCodeServiceTest.php @@ -34,12 +34,6 @@ class MfaDuoVerifyDuoCodeServiceTest extends TestCase use TruncateDirtyTables; use MfaOrgSettingsTestTrait; - public function tearDown(): void - { - parent::tearDown(); - Configure::write(MfaDuoVerifyDuoCodeService::PASSBOLT_SECURITY_MFA_DUO_VERIFY_SUBSCRIBER, false); - } - public function testMfaDuoVerifyDuoCodeService_Success() { $settings = $this->getDefaultMfaOrgSettings(); diff --git a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/IsMfaEnabledServiceTest.php b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/IsMfaEnabledServiceTest.php index e887f36750..7098c799bd 100644 --- a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/IsMfaEnabledServiceTest.php +++ b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/IsMfaEnabledServiceTest.php @@ -50,6 +50,7 @@ class IsMfaEnabledServiceTest extends TestCase public function setUp(): void { + parent::setUp(); $this->mfaOrgSettingsMock = $this->createMock(MfaOrgSettings::class); $this->getMfaAccountSettingsServiceMock = $this->createMock(GetMfaAccountSettingsService::class); $this->mfaOrgSettingsGetServiceMock = $this->createMock(MfaOrgSettingsGetService::class); @@ -58,8 +59,6 @@ public function setUp(): void $this->mfaOrgSettingsGetServiceMock, $this->getMfaAccountSettingsServiceMock ); - - parent::setUp(); } public function testThatIsEnabledForUserReturnFalseWhenOrgIsNotEnabled() diff --git a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/MfaRateLimiterServiceTest.php b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/MfaRateLimiterServiceTest.php index 5cddb839a7..2d4a59a8be 100644 --- a/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/MfaRateLimiterServiceTest.php +++ b/plugins/PassboltCe/MultiFactorAuthentication/tests/TestCase/Service/MfaRateLimiterServiceTest.php @@ -41,7 +41,6 @@ class MfaRateLimiterServiceTest extends AppTestCase public function setUp(): void { parent::setUp(); - $this->enableFeaturePlugin(MultiFactorAuthenticationPlugin::class); $this->service = new MfaRateLimiterService(); } @@ -51,9 +50,7 @@ public function setUp(): void */ public function tearDown(): void { - $this->disableFeaturePlugin(MultiFactorAuthenticationPlugin::class); unset($this->service); - parent::tearDown(); } diff --git a/plugins/PassboltCe/PasswordExpiry/src/Model/Table/PasswordExpirySettingsTable.php b/plugins/PassboltCe/PasswordExpiry/src/Model/Table/PasswordExpirySettingsTable.php index 8ab126acc9..280a0d6950 100644 --- a/plugins/PassboltCe/PasswordExpiry/src/Model/Table/PasswordExpirySettingsTable.php +++ b/plugins/PassboltCe/PasswordExpiry/src/Model/Table/PasswordExpirySettingsTable.php @@ -71,7 +71,7 @@ public function validationDefault(Validator $validator): Validator $validator->remove('value'); $validator->requirePresence('value', true, __('A value is required.')); - $validator->isArray('value', __('The value should be an array.')); + $validator->array('value', __('The value should be an array.')); return $validator; } diff --git a/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Resources/PasswordExpiryResourcesUpdateControllerTest.php b/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Resources/PasswordExpiryResourcesUpdateControllerTest.php index e2434d6a13..3477be977b 100644 --- a/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Resources/PasswordExpiryResourcesUpdateControllerTest.php +++ b/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Resources/PasswordExpiryResourcesUpdateControllerTest.php @@ -24,6 +24,7 @@ use Cake\I18n\FrozenDate; use Cake\I18n\FrozenTime; use Passbolt\Folders\Test\Factory\ResourceFactory; +use Passbolt\PasswordExpiry\PasswordExpiryPlugin; use Passbolt\PasswordExpiry\Test\Factory\PasswordExpirySettingFactory; use Passbolt\ResourceTypes\Test\Factory\ResourceTypeFactory; @@ -31,11 +32,17 @@ class PasswordExpiryResourcesUpdateControllerTest extends AppIntegrationTestCase { use EmailQueueTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(PasswordExpiryPlugin::class); + PasswordExpirySettingFactory::make()->persist(); + } + public function testPasswordExpiryResourcesUpdateController_Update_Expiry_Date_In_Future(): void { RoleFactory::make()->guest()->persist(); ResourceTypeFactory::make()->default()->persist(); - PasswordExpirySettingFactory::make()->persist(); $operator = UserFactory::make()->user()->persist(); @@ -70,7 +77,6 @@ public function testPasswordExpiryResourcesUpdateController_Update_Expiry_Date_I { RoleFactory::make()->guest()->persist(); ResourceTypeFactory::make()->default()->persist(); - PasswordExpirySettingFactory::make()->persist(); if ($isResourceAlreadyExpired) { $expiryDate = FrozenTime::yesterday(); diff --git a/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Users/PasswordExpiryUsersDeleteControllerTest.php b/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Users/PasswordExpiryUsersDeleteControllerTest.php index 30120ee18a..394e6d05a1 100644 --- a/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Users/PasswordExpiryUsersDeleteControllerTest.php +++ b/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Users/PasswordExpiryUsersDeleteControllerTest.php @@ -23,6 +23,7 @@ use App\Test\Lib\AppIntegrationTestCase; use App\Test\Lib\Model\EmailQueueTrait; use Passbolt\Log\Test\Factory\SecretAccessFactory; +use Passbolt\PasswordExpiry\PasswordExpiryPlugin; use Passbolt\PasswordExpiry\Test\Factory\PasswordExpirySettingFactory; class PasswordExpiryUsersDeleteControllerTest extends AppIntegrationTestCase @@ -33,12 +34,12 @@ public function setUp(): void { parent::setUp(); RoleFactory::make()->guest()->persist(); + PasswordExpirySettingFactory::make()->persist(); + $this->enableFeaturePlugin(PasswordExpiryPlugin::class); } public function testPasswordExpiryUsersDeleteController_Success_Expire_Resources(): void { - PasswordExpirySettingFactory::make()->persist(); - [$owner, $userToDelete] = UserFactory::make(2)->user()->persist(); [$resourceSharedViewed, $resourceSharedNotViewed] = ResourceFactory::make(2) diff --git a/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Users/PasswordExpiryUsersEditDisableControllerTest.php b/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Users/PasswordExpiryUsersEditDisableControllerTest.php index b4693fc12c..ccc9ade412 100644 --- a/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Users/PasswordExpiryUsersEditDisableControllerTest.php +++ b/plugins/PassboltCe/PasswordExpiry/tests/TestCase/Controller/Users/PasswordExpiryUsersEditDisableControllerTest.php @@ -24,6 +24,7 @@ use App\Test\Lib\Model\EmailQueueTrait; use Cake\I18n\FrozenTime; use Passbolt\Log\Test\Factory\SecretAccessFactory; +use Passbolt\PasswordExpiry\PasswordExpiryPlugin; use Passbolt\PasswordExpiry\Test\Factory\PasswordExpirySettingFactory; class PasswordExpiryUsersEditDisableControllerTest extends AppIntegrationTestCase @@ -37,12 +38,12 @@ public function setUp(): void // Mock user agent and IP $this->mockUserAgent('PHPUnit'); $this->mockUserIp(); + $this->enableFeaturePlugin(PasswordExpiryPlugin::class); + PasswordExpirySettingFactory::make()->persist(); } public function testPasswordExpiryUsersEditDisableController_Success_Admin_Disable_User(): void { - PasswordExpirySettingFactory::make()->persist(); - [$admin1, $admin2] = UserFactory::make(2)->admin()->persist(); [$userToDisable, $ownerWithResourceShared1, $ownerWithGroupShared1] = UserFactory::make(3)->user()->persist(); [$resourceSharedViewed, $resourceSharedNotViewed] = ResourceFactory::make(2) diff --git a/plugins/PassboltCe/PasswordPolicies/tests/TestCase/Controller/PasswordPoliciesSettingsGetControllerTest.php b/plugins/PassboltCe/PasswordPolicies/tests/TestCase/Controller/PasswordPoliciesSettingsGetControllerTest.php index d9d514322d..f3f4404d14 100644 --- a/plugins/PassboltCe/PasswordPolicies/tests/TestCase/Controller/PasswordPoliciesSettingsGetControllerTest.php +++ b/plugins/PassboltCe/PasswordPolicies/tests/TestCase/Controller/PasswordPoliciesSettingsGetControllerTest.php @@ -29,6 +29,12 @@ class PasswordPoliciesSettingsGetControllerTest extends AppIntegrationTestCase { use PasswordPoliciesModelTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(PasswordPoliciesPlugin::class); + } + public function testPasswordPoliciesSettingsGetController_ErrorUnauthenticated() { $this->getJson('/password-policies/settings.json'); diff --git a/plugins/PassboltCe/Rbacs/tests/Lib/RbacsIntegrationTestCase.php b/plugins/PassboltCe/Rbacs/tests/Lib/RbacsIntegrationTestCase.php index 5ddbddc1b3..0b6424f40e 100644 --- a/plugins/PassboltCe/Rbacs/tests/Lib/RbacsIntegrationTestCase.php +++ b/plugins/PassboltCe/Rbacs/tests/Lib/RbacsIntegrationTestCase.php @@ -26,10 +26,4 @@ public function setUp(): void parent::setUp(); $this->enableFeaturePlugin(RbacsPlugin::class); } - - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin(RbacsPlugin::class); - } } diff --git a/plugins/PassboltCe/Rbacs/tests/Lib/RbacsTestCase.php b/plugins/PassboltCe/Rbacs/tests/Lib/RbacsTestCase.php index 05a080c552..2c35dec30a 100644 --- a/plugins/PassboltCe/Rbacs/tests/Lib/RbacsTestCase.php +++ b/plugins/PassboltCe/Rbacs/tests/Lib/RbacsTestCase.php @@ -26,10 +26,4 @@ public function setUp(): void parent::setUp(); $this->enableFeaturePlugin(RbacsPlugin::class); } - - public function tearDown(): void - { - parent::tearDown(); - $this->disableFeaturePlugin(RbacsPlugin::class); - } } diff --git a/plugins/PassboltCe/ResourceTypes/tests/TestCase/Controller/ResourceTypesIndexControllerTest.php b/plugins/PassboltCe/ResourceTypes/tests/TestCase/Controller/ResourceTypesIndexControllerTest.php index 79608a4e61..ea1b4861ef 100644 --- a/plugins/PassboltCe/ResourceTypes/tests/TestCase/Controller/ResourceTypesIndexControllerTest.php +++ b/plugins/PassboltCe/ResourceTypes/tests/TestCase/Controller/ResourceTypesIndexControllerTest.php @@ -18,6 +18,7 @@ namespace Passbolt\ResourceTypes\Test\TestCase\Controller; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\ResourceTypes\ResourceTypesPlugin; use Passbolt\ResourceTypes\Test\Lib\Model\ResourceTypesModelTrait; use Passbolt\ResourceTypes\Test\Scenario\ResourceTypesScenario; @@ -28,6 +29,12 @@ class ResourceTypesIndexControllerTest extends AppIntegrationTestCase { use ResourceTypesModelTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(ResourceTypesPlugin::class); + } + public function testResourceTypesIndex_Success() { $this->loadFixtureScenario(ResourceTypesScenario::class); diff --git a/plugins/PassboltCe/ResourceTypes/tests/TestCase/Controller/ResourceTypesViewControllerTest.php b/plugins/PassboltCe/ResourceTypes/tests/TestCase/Controller/ResourceTypesViewControllerTest.php index 511b09ea94..ebd7d9000a 100644 --- a/plugins/PassboltCe/ResourceTypes/tests/TestCase/Controller/ResourceTypesViewControllerTest.php +++ b/plugins/PassboltCe/ResourceTypes/tests/TestCase/Controller/ResourceTypesViewControllerTest.php @@ -19,6 +19,7 @@ use App\Test\Lib\AppIntegrationTestCase; use App\Utility\UuidFactory; +use Passbolt\ResourceTypes\ResourceTypesPlugin; use Passbolt\ResourceTypes\Test\Factory\ResourceTypeFactory; use Passbolt\ResourceTypes\Test\Lib\Model\ResourceTypesModelTrait; @@ -29,6 +30,12 @@ class ResourceTypesViewControllerTest extends AppIntegrationTestCase { use ResourceTypesModelTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(ResourceTypesPlugin::class); + } + public function testResourceTypesView_Success() { $this->logInAsUser(); diff --git a/plugins/PassboltCe/SelfRegistration/src/Service/Healthcheck/SelfRegistrationHealthcheckService.php b/plugins/PassboltCe/SelfRegistration/src/Service/Healthcheck/SelfRegistrationHealthcheckService.php index bca86303a8..247016994c 100644 --- a/plugins/PassboltCe/SelfRegistration/src/Service/Healthcheck/SelfRegistrationHealthcheckService.php +++ b/plugins/PassboltCe/SelfRegistration/src/Service/Healthcheck/SelfRegistrationHealthcheckService.php @@ -28,6 +28,13 @@ class SelfRegistrationHealthcheckService { use FeaturePluginAwareTrait; + /** + * Used for caching self registration settings. + * + * @var array|null + */ + private ?array $selfRegistrationSettings = null; + /** * @return array */ @@ -62,7 +69,12 @@ protected function selfRegistrationProvider(): ?string } try { - $settings = (new SelfRegistrationGetSettingsService())->getSettings(); + if (is_null($this->selfRegistrationSettings)) { + $settings = (new SelfRegistrationGetSettingsService())->getSettings(); + $this->selfRegistrationSettings = $settings; + } else { + $settings = $this->selfRegistrationSettings; + } } catch (FormValidationException | MissingConnectionException | InternalErrorException $e) { return null; } diff --git a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationDeleteSettingsControllerTest.php b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationDeleteSettingsControllerTest.php index 467767bb1f..b4f91f5232 100644 --- a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationDeleteSettingsControllerTest.php +++ b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationDeleteSettingsControllerTest.php @@ -20,12 +20,19 @@ use App\Test\Factory\OrganizationSettingFactory; use App\Test\Lib\AppIntegrationTestCase; use App\Utility\UuidFactory; +use Passbolt\SelfRegistration\SelfRegistrationPlugin; use Passbolt\SelfRegistration\Test\Lib\SelfRegistrationTestTrait; class SelfRegistrationDeleteSettingsControllerTest extends AppIntegrationTestCase { use SelfRegistrationTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); + } + public function testSelfRegistrationDeleteSettingsControllerTest_Success() { $this->logInAsAdmin(); diff --git a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationDryRunControllerTest.php b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationDryRunControllerTest.php index d5266337cb..5f582da7a1 100644 --- a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationDryRunControllerTest.php +++ b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationDryRunControllerTest.php @@ -18,12 +18,19 @@ namespace Passbolt\SelfRegistration\Test\TestCase\Controller; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\SelfRegistration\SelfRegistrationPlugin; use Passbolt\SelfRegistration\Test\Lib\SelfRegistrationTestTrait; class SelfRegistrationDryRunControllerTest extends AppIntegrationTestCase { use SelfRegistrationTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); + } + public function testSelfRegistrationDryRunControllerTest_Success() { $this->setSelfRegistrationSettingsData(); diff --git a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationGetSettingsControllerTest.php b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationGetSettingsControllerTest.php index 0397e11221..b4970c8e11 100644 --- a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationGetSettingsControllerTest.php +++ b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationGetSettingsControllerTest.php @@ -18,12 +18,19 @@ namespace Passbolt\SelfRegistration\Test\TestCase\Controller; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\SelfRegistration\SelfRegistrationPlugin; use Passbolt\SelfRegistration\Test\Lib\SelfRegistrationTestTrait; class SelfRegistrationGetSettingsControllerTest extends AppIntegrationTestCase { use SelfRegistrationTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); + } + public function testSelfRegistrationGetSettingsControllerTest_Success() { $this->logInAsAdmin(); diff --git a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationSetSettingsControllerTest.php b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationSetSettingsControllerTest.php index 9468ef51d5..c87723f506 100644 --- a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationSetSettingsControllerTest.php +++ b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/SelfRegistrationSetSettingsControllerTest.php @@ -21,6 +21,7 @@ use App\Test\Factory\UserFactory; use App\Test\Lib\AppIntegrationTestCase; use App\Test\Lib\Model\EmailQueueTrait; +use Passbolt\SelfRegistration\SelfRegistrationPlugin; use Passbolt\SelfRegistration\Test\Lib\SelfRegistrationTestTrait; class SelfRegistrationSetSettingsControllerTest extends AppIntegrationTestCase @@ -28,6 +29,12 @@ class SelfRegistrationSetSettingsControllerTest extends AppIntegrationTestCase use EmailQueueTrait; use SelfRegistrationTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); + } + public function testSelfRegistrationSetSettingsControllerTest_Success() { $admin = $this->logInAsAdmin(); diff --git a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Settings/SettingsIndexControllerTest.php b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Settings/SettingsIndexControllerTest.php index 01ef7a49d2..fe7c2fc1db 100644 --- a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Settings/SettingsIndexControllerTest.php +++ b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Settings/SettingsIndexControllerTest.php @@ -18,9 +18,16 @@ namespace Passbolt\SelfRegistration\Test\TestCase\Controller\Settings; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\SelfRegistration\SelfRegistrationPlugin; class SettingsIndexControllerTest extends AppIntegrationTestCase { + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); + } + public function testSettingsIndexController_publicPluginSettings() { $url = '/settings.json?api-version=2'; diff --git a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Users/SelfRegistrationUsersRecoverControllerTest.php b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Users/SelfRegistrationUsersRecoverControllerTest.php index 13e1260287..fa57d70d91 100644 --- a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Users/SelfRegistrationUsersRecoverControllerTest.php +++ b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Users/SelfRegistrationUsersRecoverControllerTest.php @@ -17,6 +17,7 @@ namespace Passbolt\SelfRegistration\Test\TestCase\Controller\Users; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\SelfRegistration\SelfRegistrationPlugin; use Passbolt\SelfRegistration\Test\Lib\SelfRegistrationTestTrait; /** @@ -26,6 +27,12 @@ class SelfRegistrationUsersRecoverControllerTest extends AppIntegrationTestCase { use SelfRegistrationTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); + } + public function testSelfRegistrationUsersRecoverController_SelfRegistrationOpen_UserNotFound_Domain_Not_Supported() { $this->setSelfRegistrationSettingsData(); diff --git a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Users/SelfRegistrationUsersRegisterControllerTest.php b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Users/SelfRegistrationUsersRegisterControllerTest.php index bb48b28d52..130494bd42 100644 --- a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Users/SelfRegistrationUsersRegisterControllerTest.php +++ b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Controller/Users/SelfRegistrationUsersRegisterControllerTest.php @@ -21,6 +21,7 @@ use App\Test\Lib\AppIntegrationTestCase; use App\Test\Lib\Model\EmailQueueTrait; use Cake\ORM\TableRegistry; +use Passbolt\SelfRegistration\SelfRegistrationPlugin; use Passbolt\SelfRegistration\Test\Lib\SelfRegistrationTestTrait; /** @@ -31,6 +32,12 @@ class SelfRegistrationUsersRegisterControllerTest extends AppIntegrationTestCase use EmailQueueTrait; use SelfRegistrationTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SelfRegistrationPlugin::class); + } + public function testSelfRegistrationUsersRegisterController_SelfRegistrationClosed() { $this->get('/users/register'); diff --git a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Form/Settings/SelfRegistrationEmailDomainsSettingsFormTest.php b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Form/Settings/SelfRegistrationEmailDomainsSettingsFormTest.php index e879918ef9..8fc61dbf16 100644 --- a/plugins/PassboltCe/SelfRegistration/tests/TestCase/Form/Settings/SelfRegistrationEmailDomainsSettingsFormTest.php +++ b/plugins/PassboltCe/SelfRegistration/tests/TestCase/Form/Settings/SelfRegistrationEmailDomainsSettingsFormTest.php @@ -40,7 +40,6 @@ public function tearDown(): void { parent::tearDown(); unset($this->form); - Configure::write(EmailValidationRule::MX_CHECK_KEY, false); } public function testSelfRegistrationEmailDomainsSettingsForm_With_Valid_Provider_And_Data_Valid_Should_Succeed() diff --git a/plugins/PassboltCe/SmtpSettings/src/Event/SmtpTransportBeforeSendEventListener.php b/plugins/PassboltCe/SmtpSettings/src/Event/SmtpTransportBeforeSendEventListener.php index 077be6424c..6632633afd 100644 --- a/plugins/PassboltCe/SmtpSettings/src/Event/SmtpTransportBeforeSendEventListener.php +++ b/plugins/PassboltCe/SmtpSettings/src/Event/SmtpTransportBeforeSendEventListener.php @@ -20,6 +20,7 @@ use Cake\Event\EventInterface; use Cake\Event\EventListenerInterface; use Passbolt\SmtpSettings\Service\SmtpSettingsGetSettingsInDbService; +use Passbolt\SmtpSettings\Service\SmtpSettingsSslOptionsGetService; class SmtpTransportBeforeSendEventListener implements EventListenerInterface { @@ -61,24 +62,32 @@ public function getConfigInDB(): ?array */ public function initializeTransport(EventInterface $event): void { - $this->configInDB = (new SmtpSettingsGetSettingsInDbService())->getSettings(); - if (is_null($this->configInDB)) { - return; - } /** @var \App\Mailer\Transport\SmtpTransport $transport */ $transport = $event->getSubject(); $defaultConfig = $event->getData(); - $configToMerge = [ - 'className' => self::class, - 'sender_name' => $this->configInDB['sender_name'], - 'sender_email' => $this->configInDB['sender_email'], - 'host' => $this->configInDB['host'], - 'port' => $this->configInDB['port'], - 'tls' => $this->configInDB['tls'] ?? null, - 'client' => $this->configInDB['client'], - 'username' => $this->configInDB['username'], - 'password' => $this->configInDB['password'], - ]; + $configToMerge = []; + + $this->configInDB = (new SmtpSettingsGetSettingsInDbService())->getSettings(); + if (!is_null($this->configInDB)) { + $configToMerge = [ + 'className' => self::class, + 'sender_name' => $this->configInDB['sender_name'], + 'sender_email' => $this->configInDB['sender_email'], + 'host' => $this->configInDB['host'], + 'port' => $this->configInDB['port'], + 'tls' => $this->configInDB['tls'] ?? null, + 'client' => $this->configInDB['client'], + 'username' => $this->configInDB['username'], + 'password' => $this->configInDB['password'], + ]; + } + + // Merge SSL Options if present in config + $sslOptions = (new SmtpSettingsSslOptionsGetService())->get(); + if (!empty($sslOptions)) { + $configToMerge['context'] = ['ssl' => $sslOptions]; + } + $transport->setConfig(array_merge($defaultConfig, $configToMerge)); } diff --git a/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SettingsValidationSmtpSettingsHealthcheck.php b/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SettingsValidationSmtpSettingsHealthcheck.php new file mode 100644 index 0000000000..f4e8efbbb4 --- /dev/null +++ b/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SettingsValidationSmtpSettingsHealthcheck.php @@ -0,0 +1,141 @@ +passboltFileName = $passboltFileName; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + try { + $getService = new SmtpSettingsGetService($this->passboltFileName); + $getService->getSettings(); + $this->status = true; + } catch (FormValidationException $e) { + $this->validationError = json_encode($e->getErrors()); + } catch (InternalErrorException $e) { + $this->validationError = $e->getMessage(); + } catch (\Throwable $e) { + $this->validationError = $e->getMessage(); + } + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_SMTP_SETTINGS; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('SMTP Settings coherent. You may send a test email to validate them.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('SMTP Setting errors: {0}', $this->validationError); + } + + /** + * @return string + */ + public function getValidationError(): string + { + return $this->validationError; + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): ?string + { + return null; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_SMTP_SETTINGS; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'errorMessage'; + } +} diff --git a/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SmtpSettingsEndpointsDisabledHealthcheck.php b/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SmtpSettingsEndpointsDisabledHealthcheck.php new file mode 100644 index 0000000000..ecec42f9f4 --- /dev/null +++ b/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SmtpSettingsEndpointsDisabledHealthcheck.php @@ -0,0 +1,116 @@ +status = Configure::read( + SmtpSettingsSecurityMiddleware::PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED + ); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_SMTP_SETTINGS; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The {0} plugin endpoints are disabled.', 'SMTP Settings'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The {0} plugin endpoints are enabled.', 'SMTP Settings'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): array + { + return [ + __('It is recommended to disable the plugin endpoints.'), + __('Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true.'), + __('Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}.', CONFIG . 'passbolt.php'), + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_SMTP_SETTINGS; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'areEndpointsDisabled'; + } +} diff --git a/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SmtpSettingsSettingsSourceHealthcheck.php b/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SmtpSettingsSettingsSourceHealthcheck.php new file mode 100644 index 0000000000..937a6309a3 --- /dev/null +++ b/plugins/PassboltCe/SmtpSettings/src/Service/Healthcheck/SmtpSettingsSettingsSourceHealthcheck.php @@ -0,0 +1,165 @@ +passboltFileName = $passboltFileName; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + $getService = new SmtpSettingsGetService($this->passboltFileName); + + try { + $smtpSettings = $getService->getSettings(); + $source = $smtpSettings['source']; + } catch (FormValidationException $e) { + $source = $e->getForm()->getData('source'); + } catch (InternalErrorException $e) { + $source = SmtpSettingsGetService::SMTP_SETTINGS_SOURCE_DB; + } catch (\Throwable $e) { + $source = SmtpSettingsGetService::SMTP_SETTINGS_SOURCE_UNDEFINED; + } + + $this->source = $this->mapSource($source) ?? __('not found'); + $isInDb = $source === SmtpSettingsGetService::SMTP_SETTINGS_SOURCE_DB; + $this->status = $isInDb; + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_SMTP_SETTINGS; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The SMTP Settings source is: {0}.', $this->source); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return $this->getSuccessMessage(); + } + + /** + * @return string + */ + public function getSource(): string + { + return $this->source; + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): string + { + return __('It is recommended to set the SMTP Settings in the database through the administration section.'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_SMTP_SETTINGS; + } + + /** + * The case where the source is not defined should code-based never occur, but just in case + * and in order preserve the healthcheck integrity we cover the un defined case. + * + * @param string $source source to map into human intelligible string + * @return string|null + */ + protected function mapSource(string $source): ?string + { + $map = [ + SmtpSettingsGetService::SMTP_SETTINGS_SOURCE_DB => __('database'), + SmtpSettingsGetService::SMTP_SETTINGS_SOURCE_FILE => CONFIG . 'passbolt.php', + SmtpSettingsGetService::SMTP_SETTINGS_SOURCE_ENV => __('env variables'), + SmtpSettingsGetService::SMTP_SETTINGS_SOURCE_UNDEFINED => __('undefined'), + ]; + + return $map[$source] ?? null; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'isInDb'; + } +} diff --git a/plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSendTestMailerService.php b/plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSendTestMailerService.php index bcbc089f4d..b4924f5213 100644 --- a/plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSendTestMailerService.php +++ b/plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSendTestMailerService.php @@ -73,6 +73,12 @@ private function setSmtpSettings(array $smtpSettings): void 'client' => $smtpSettings['client'], ]; + // Merge SSL Options if present in config + $sslOptions = (new SmtpSettingsSslOptionsGetService())->get(); + if (!empty($sslOptions)) { + $config['context'] = ['ssl' => $sslOptions]; + } + if ($this->isRunningOnTestEnvironment()) { $debugTransport = TransportFactory::get('default'); } else { diff --git a/plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSslOptionsGetService.php b/plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSslOptionsGetService.php new file mode 100644 index 0000000000..2bc069c9e3 --- /dev/null +++ b/plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsSslOptionsGetService.php @@ -0,0 +1,97 @@ +isDefault($configSslOptions)) { + return []; + } + + return $this->getMappedOptions($configSslOptions); + } + + /** + * Checks if SSL options set in configuration are defaults. + * + * @param array $configOptions SSL options set in configuration. + * @return bool + */ + private function isDefault(array $configOptions): bool + { + if (count($configOptions) !== 4) { + return false; + } + + $defaults = [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => false, + 'cafile' => null, + ]; + + $result = $this->getMappedOptions($configOptions); + + return empty(array_diff_assoc($defaults, $result)); + } + + /** + * @param array $configSslOptions Config SSL options. + * @return array + */ + private function getMappedOptions(array $configSslOptions): array + { + $result = []; + $mapping = $this->getMapping(); + + foreach ($configSslOptions as $key => $value) { + if (!isset($mapping[$key])) { + // skip if mapping not found + continue; + } + + $result[$mapping[$key]] = $value; + } + + return $result; + } + + /** + * @return string[] + */ + private function getMapping(): array + { + return [ + 'sslVerifyPeer' => 'verify_peer', + 'sslVerifyPeerName' => 'verify_peer_name', + 'sslAllowSelfSigned' => 'allow_self_signed', + 'sslCafile' => 'cafile', + ]; + } +} diff --git a/plugins/PassboltCe/SmtpSettings/src/SmtpSettingsPlugin.php b/plugins/PassboltCe/SmtpSettings/src/SmtpSettingsPlugin.php index f3cb3f221c..e0a2fed887 100644 --- a/plugins/PassboltCe/SmtpSettings/src/SmtpSettingsPlugin.php +++ b/plugins/PassboltCe/SmtpSettings/src/SmtpSettingsPlugin.php @@ -16,9 +16,14 @@ */ namespace Passbolt\SmtpSettings; +use App\Service\Healthcheck\HealthcheckServiceCollector; use Cake\Core\BasePlugin; +use Cake\Core\ContainerInterface; use Cake\Core\PluginApplicationInterface; use Passbolt\SmtpSettings\Event\SmtpTransportBeforeSendEventListener; +use Passbolt\SmtpSettings\Service\Healthcheck\SettingsValidationSmtpSettingsHealthcheck; +use Passbolt\SmtpSettings\Service\Healthcheck\SmtpSettingsEndpointsDisabledHealthcheck; +use Passbolt\SmtpSettings\Service\Healthcheck\SmtpSettingsSettingsSourceHealthcheck; class SmtpSettingsPlugin extends BasePlugin { @@ -32,4 +37,19 @@ public function bootstrap(PluginApplicationInterface $app): void // Before sending an email, apply the SMTP settings found in DB (or fallback on file). $app->getEventManager()->on(new SmtpTransportBeforeSendEventListener()); } + + /** + * @inheritDoc + */ + public function services(ContainerInterface $container): void + { + $container->add(SettingsValidationSmtpSettingsHealthcheck::class); + $container->add(SmtpSettingsSettingsSourceHealthcheck::class); + $container->add(SmtpSettingsEndpointsDisabledHealthcheck::class); + $container + ->extend(HealthcheckServiceCollector::class) + ->addMethodCall('addService', [SettingsValidationSmtpSettingsHealthcheck::class]) + ->addMethodCall('addService', [SmtpSettingsSettingsSourceHealthcheck::class]) + ->addMethodCall('addService', [SmtpSettingsEndpointsDisabledHealthcheck::class]); + } } diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Command/SmtpSettingsHealthcheckCommandTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Command/SmtpSettingsHealthcheckCommandTest.php index 55ef9ed64c..5434d3e367 100644 --- a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Command/SmtpSettingsHealthcheckCommandTest.php +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Command/SmtpSettingsHealthcheckCommandTest.php @@ -16,17 +16,19 @@ */ namespace Passbolt\SmtpSettings\Test\TestCase\Command; -use App\Command\HealthcheckCommand; -use App\Test\Lib\AppTestCase; +use App\Test\Lib\AppIntegrationTestCase; use App\Test\Lib\Utility\PassboltCommandTestTrait; use Cake\Console\TestSuite\ConsoleIntegrationTestTrait; +use Cake\Core\Configure; +use Passbolt\SmtpSettings\Middleware\SmtpSettingsSecurityMiddleware; +use Passbolt\SmtpSettings\SmtpSettingsPlugin; use Passbolt\SmtpSettings\Test\Lib\SmtpSettingsTestTrait; -class SmtpSettingsHealthcheckCommandTest extends AppTestCase +class SmtpSettingsHealthcheckCommandTest extends AppIntegrationTestCase { use ConsoleIntegrationTestTrait; - use PassboltCommandTestTrait; use SmtpSettingsTestTrait; + use PassboltCommandTestTrait; /** * setUp method @@ -37,54 +39,47 @@ public function setUp(): void { parent::setUp(); $this->useCommandRunner(); - HealthcheckCommand::$isUserRoot = false; + $this->mockProcessUserService('www-data'); + $this->enableFeaturePlugin(SmtpSettingsPlugin::class); } - public function testHealthcheckCommand_SmtpSettings_Valid() + public function testHealthcheckCommand_SmtpSettings_Plugin_Disabled() { - $this->setTransportConfig(); + $this->disableFeaturePlugin(SmtpSettingsPlugin::class); $this->exec('passbolt healthcheck --smtpSettings'); $this->assertExitSuccess(); - if ($this->isFeaturePluginEnabled('SmtpSettings')) { - $this->assertOutputContains('[PASS] The SMTP Settings plugin is enabled.'); - $this->assertOutputContains('[WARN] The SMTP Settings source is: '); - } else { - $this->assertOutputContains(' [WARN] The {0} plugin is disabled. Enable the plugin in order to define SMTP settings in the database.'); - } + $this->assertOutputContains('[WARN] The SMTP Settings plugin is disabled.'); + $this->assertOutputContains('[HELP] Enable the plugin in order to define SMTP settings in the database.'); $this->assertOutputContains('No error found. Nice one sparky!'); } - public function testHealthcheckCommand_SmtpSettings_Invalid() + public function testHealthcheckCommand_SmtpSettings_Valid() { - if ($this->isFeaturePluginEnabled('SmtpSettings')) { - $data = $this->getSmtpSettingsData('host', ''); - $this->encryptAndPersistSmtpSettings($data); - } - + Configure::write( + SmtpSettingsSecurityMiddleware::PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED, + true + ); + $this->setTransportConfig(); + $data = $this->getSmtpSettingsData(); + $this->encryptAndPersistSmtpSettings($data); $this->exec('passbolt healthcheck --smtpSettings'); $this->assertExitSuccess(); - if ($this->isFeaturePluginEnabled('SmtpSettings')) { - $validationErrorMessage = '[FAIL] SMTP Setting errors: {"host":{"_empty":"The host name should not be empty."}}'; - $this->assertOutputContains('[PASS] The SMTP Settings plugin is enabled.'); - $this->assertOutputContains('[PASS] The SMTP Settings source is: database.'); - $this->assertOutputContains($validationErrorMessage); - $this->assertOutputContains(' 1 error(s) found. Hang in there!'); - } else { - $this->assertOutputContains(' [WARN] The {0} plugin is disabled. Enable the plugin in order to define SMTP settings in the database.'); - $this->assertOutputContains('No error found. Nice one sparky!'); - } + $this->assertOutputContains('[PASS] The SMTP Settings plugin is enabled.'); + $this->assertOutputContains('[PASS] SMTP Settings coherent. You may send a test email to validate them.'); + $this->assertOutputContains('[PASS] The SMTP Settings source is: database.'); + $this->assertOutputContains('[PASS] The SMTP Settings plugin endpoints are disabled.'); + $this->assertOutputContains('No error found. Nice one sparky!'); } - public function testHealthcheckCommand_SmtpSettings_Plugin_Deactivated() + public function testHealthcheckCommand_SmtpSettings_Invalid() { - $wasPluginEnabled = $this->isFeaturePluginEnabled('SmtpSettings'); - $this->disableFeaturePlugin('SmtpSettings'); + $this->setTransportConfig('port', 0); $this->exec('passbolt healthcheck --smtpSettings'); $this->assertExitSuccess(); - $this->assertOutputContains(' [WARN] The SMTP Settings plugin is disabled. Enable the plugin in order to define SMTP settings in the database.'); - $this->assertOutputContains('No error found. Nice one sparky!'); - if ($wasPluginEnabled) { - $this->enableFeaturePlugin('SmtpSettings'); - } + $this->assertOutputContains('[PASS] The SMTP Settings plugin is enabled.'); + $this->assertOutputContains('[FAIL] SMTP Setting errors: {"port":{"range":"The port number should be between 1 and 65535."}}'); + $this->assertOutputContains('[WARN] The SMTP Settings source is:'); + $this->assertOutputContains('[WARN] The SMTP Settings plugin endpoints are enabled.'); + $this->assertOutputContains('[HELP] It is recommended to disable the plugin endpoints.'); } } diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/Settings/SmtpSettingsSettingsIndexControllerTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/Settings/SmtpSettingsSettingsIndexControllerTest.php index a376cef9b7..408541541d 100644 --- a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/Settings/SmtpSettingsSettingsIndexControllerTest.php +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/Settings/SmtpSettingsSettingsIndexControllerTest.php @@ -18,9 +18,16 @@ namespace Passbolt\SmtpSettings\Test\TestCase\Controller\Settings; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\SmtpSettings\SmtpSettingsPlugin; class SmtpSettingsSettingsIndexControllerTest extends AppIntegrationTestCase { + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SmtpSettingsPlugin::class); + } + public function testSmtpSettingsSettingsIndexControllerTest() { $url = '/settings.json?api-version=2'; diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsEmailControllerTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsEmailControllerTest.php index 9039b0326c..a3461b7252 100644 --- a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsEmailControllerTest.php +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsEmailControllerTest.php @@ -20,6 +20,7 @@ use App\Test\Lib\AppIntegrationTestCase; use App\Test\Lib\Utility\EmailTestTrait; use Passbolt\SmtpSettings\Service\SmtpSettingsSendTestMailerService; +use Passbolt\SmtpSettings\SmtpSettingsPlugin; use Passbolt\SmtpSettings\Test\Factory\SmtpSettingFactory; use Passbolt\SmtpSettings\Test\Lib\SmtpSettingsIntegrationTestTrait; use Passbolt\SmtpSettings\Test\Lib\SmtpSettingsTestTrait; @@ -33,6 +34,12 @@ class SmtpSettingsEmailControllerTest extends AppIntegrationTestCase use SmtpSettingsIntegrationTestTrait; use SmtpSettingsTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SmtpSettingsPlugin::class); + } + public function testSmtpSettingsEmailController_Success() { // Insert some dummy SMTP settings in the DB to ensure that these are ignored by the DebugSmtpTransport diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsGetControllerTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsGetControllerTest.php index b5f80be6a7..037ea8acf0 100644 --- a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsGetControllerTest.php +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsGetControllerTest.php @@ -18,12 +18,19 @@ namespace Passbolt\SmtpSettings\Test\TestCase\Controller; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\SmtpSettings\SmtpSettingsPlugin; use Passbolt\SmtpSettings\Test\Lib\SmtpSettingsTestTrait; class SmtpSettingsGetControllerTest extends AppIntegrationTestCase { use SmtpSettingsTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SmtpSettingsPlugin::class); + } + public function testSmtpSettingsGetController_Success() { $this->logInAsAdmin(); diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsPostControllerTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsPostControllerTest.php index 282f477328..718b399390 100644 --- a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsPostControllerTest.php +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Controller/SmtpSettingsPostControllerTest.php @@ -18,6 +18,7 @@ namespace Passbolt\SmtpSettings\Test\TestCase\Controller; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\SmtpSettings\SmtpSettingsPlugin; use Passbolt\SmtpSettings\Test\Factory\SmtpSettingFactory; use Passbolt\SmtpSettings\Test\Lib\SmtpSettingsTestTrait; @@ -25,6 +26,12 @@ class SmtpSettingsPostControllerTest extends AppIntegrationTestCase { use SmtpSettingsTestTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(SmtpSettingsPlugin::class); + } + public function testSmtpSettingsPostController_Success() { $this->gpgSetup(); diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Event/SmtpTransportBeforeSendEventListenerTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Event/SmtpTransportBeforeSendEventListenerTest.php index 6e2d15d82a..edf8b609ba 100644 --- a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Event/SmtpTransportBeforeSendEventListenerTest.php +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Event/SmtpTransportBeforeSendEventListenerTest.php @@ -18,6 +18,7 @@ namespace Passbolt\SmtpSettings\Test\TestCase\Event; use App\Mailer\Transport\SmtpTransport; +use Cake\Core\Configure; use Cake\Event\Event; use Cake\Mailer\Message; use Cake\TestSuite\TestCase; @@ -113,4 +114,80 @@ public function testSmtpTransportSendEventListener_SetFromWithoutSettingsInDB(): $this->assertSame($from, $message->getSender()); $this->assertSame($from, $message->getReturnPath()); } + + /** + * @return array + */ + public function smtpSettingsContextSslOptionsDataProvider(): array + { + return [ + [ + [ + 'sslVerifyPeer' => false, + 'sslVerifyPeerName' => false, + 'sslAllowSelfSigned' => true, + ], + ], + [ + [ + 'sslVerifyPeer' => true, + 'sslVerifyPeerName' => true, + 'sslAllowSelfSigned' => true, + 'sslCafile' => '/path/to/rootCA.crt', + ], + ], + [ + [], + ], + ]; + } + + /** + * @dataProvider smtpSettingsContextSslOptionsDataProvider + */ + public function testSmtpTransportSendEventListener_ContextSslOptionsAreMerged_NoDBConfig(array $options): void + { + $configInFile = $this->getSmtpSettingsData(); + $subject = new SmtpTransport($configInFile); + $event = new Event('foo', $subject, ['tls' => false]); + Configure::write('passbolt.plugins.smtpSettings.security', $options); + + $this->listener->initializeTransport($event); + + $result = $subject->getConfig(); + $this->assertFalse($result['tls']); + if (!empty($options)) { + // Assert context.ssl data is properly set + $this->assertArrayHasKey('context', $result); + $this->assertEqualsCanonicalizing($options, $result['context']['ssl']); + } else { + $this->assertArrayNotHasKey('context', $result); + } + } + + /** + * @dataProvider smtpSettingsContextSslOptionsDataProvider + */ + public function testSmtpTransportSendEventListener_ContextSslOptionsAreMerged_WithConfigInDB(array $options): void + { + $config = $this->getSmtpSettingsData(); + $config['port'] = 1025; + $config['tls'] = false; + $this->encryptAndPersistSmtpSettings($config); + $subject = new SmtpTransport($config); + $event = new Event('foo', $subject, []); + Configure::write('passbolt.plugins.smtpSettings.security', $options); + + $this->listener->initializeTransport($event); + + $result = $subject->getConfig(); + $this->assertNull($result['tls']); + if (!empty($options)) { + // Assert context.ssl data is properly set + $this->assertArrayHasKey('context', $result); + $this->assertEqualsCanonicalizing($options, $result['context']['ssl']); + } else { + $this->assertArrayNotHasKey('context', $result); + } + } } diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Middleware/SmtpSettingsSecurityMiddlewareTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Middleware/SmtpSettingsSecurityMiddlewareTest.php index fa84a9224c..9cc2d338f6 100644 --- a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Middleware/SmtpSettingsSecurityMiddlewareTest.php +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Middleware/SmtpSettingsSecurityMiddlewareTest.php @@ -34,12 +34,6 @@ public function setUp(): void $this->disableSmtpSettingsEndpoints(); } - public function tearDown(): void - { - $this->enableSmtpSettingsEndpoints(); - parent::tearDown(); - } - public function testSmtpSettingsSecurityMiddlewareTest_Should_Be_Forbidden_If_Security_Enabled() { $this->expectException(ForbiddenException::class); diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/Healthcheck/SettingsValidationSmtpSettingsHealthcheckTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/Healthcheck/SettingsValidationSmtpSettingsHealthcheckTest.php new file mode 100644 index 0000000000..695e60730a --- /dev/null +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/Healthcheck/SettingsValidationSmtpSettingsHealthcheckTest.php @@ -0,0 +1,83 @@ +service = new SettingsValidationSmtpSettingsHealthcheck($this->dummyPassboltFile); + } + + public function tearDown(): void + { + unset($this->service); + $this->deletePassboltDummyFile(); + parent::tearDown(); + } + + public function testSettingsValidationSmtpSettings_Valid_DB() + { + $data = $this->getSmtpSettingsData(); + $this->encryptAndPersistSmtpSettings($data); + + $this->service->check(); + $this->assertTrue($this->service->isPassed()); + } + + public function testSettingsValidationSmtpSettings_Invalid_DB() + { + $data = $this->getSmtpSettingsData('port', 0); + $this->encryptAndPersistSmtpSettings($data); + + $this->service->check(); + $this->assertFalse($this->service->isPassed()); + $this->assertSame( + '{"port":{"range":"The port number should be between 1 and 65535."}}', + $this->service->getValidationError() + ); + } + + public function testSettingsValidationSmtpSettings_Decryption_Error() + { + // Invalid settings + SmtpSettingFactory::make()->persist(); + + $this->service->check(); + $this->assertFalse($this->service->isPassed()); + $this->assertSame( + 'The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database. To fix this problem, you need to configure the SMTP server again. Decryption failed. decrypt failed', + $this->service->getValidationError() + ); + } +} diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/Healthcheck/SmtpSettingsSourceHealthcheckTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/Healthcheck/SmtpSettingsSourceHealthcheckTest.php new file mode 100644 index 0000000000..0aff07cf45 --- /dev/null +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/Healthcheck/SmtpSettingsSourceHealthcheckTest.php @@ -0,0 +1,108 @@ +service = new SmtpSettingsSettingsSourceHealthcheck($this->dummyPassboltFile); + } + + public function tearDown(): void + { + unset($this->service); + $this->deletePassboltDummyFile(); + parent::tearDown(); + } + + public function testSmtpSettingsSourceHealthcheck_Valid_DB() + { + $data = $this->getSmtpSettingsData(); + $this->encryptAndPersistSmtpSettings($data); + + $this->service->check(); + $this->assertTrue($this->service->isPassed()); + $this->assertSame('database', $this->service->getSource()); + } + + public function testSmtpSettingsSourceHealthcheck_Invalid_DB() + { + $data = $this->getSmtpSettingsData('port', 0); + $this->encryptAndPersistSmtpSettings($data); + + $this->service->check(); + $this->assertTrue($this->service->isPassed()); + $this->assertSame('database', $this->service->getSource()); + } + + public function testSmtpSettingsSourceHealthcheck_Valid_File() + { + $this->setTransportConfig(); + $this->makeDummyPassboltFile([ + 'EmailTransport' => 'Foo', + 'Email' => 'Bar', + ]); + + $this->service->check(); + $this->assertFalse($this->service->isPassed()); + $this->assertSame(CONFIG . 'passbolt.php', $this->service->getSource()); + } + + public function testSmtpSettingsSourceHealthcheck_Invalid_File() + { + $this->setTransportConfig('port', 0); + $this->makeDummyPassboltFile([ + 'EmailTransport' => 'Foo', + 'Email' => 'Bar', + ]); + + $this->service->check(); + $this->assertFalse($this->service->isPassed()); + $this->assertSame(CONFIG . 'passbolt.php', $this->service->getSource()); + } + + public function testSmtpSettingsSourceHealthcheck_Valid_Env() + { + $this->setTransportConfig(); + + $this->service->check(); + $this->assertFalse($this->service->isPassed()); + $this->assertSame('env variables', $this->service->getSource()); + } + + public function testSmtpSettingsSourceHealthcheck_Invalid_Env() + { + $this->setTransportConfig('port', 0); + + $this->service->check(); + $this->assertFalse($this->service->isPassed()); + $this->assertSame('env variables', $this->service->getSource()); + } +} diff --git a/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/SmtpSettingsSslOptionsGetServiceTest.php b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/SmtpSettingsSslOptionsGetServiceTest.php new file mode 100644 index 0000000000..d6f4bd8af0 --- /dev/null +++ b/plugins/PassboltCe/SmtpSettings/tests/TestCase/Service/SmtpSettingsSslOptionsGetServiceTest.php @@ -0,0 +1,125 @@ +service = new SmtpSettingsSslOptionsGetService(); + } + + public function tearDown(): void + { + unset($this->service); + + parent::tearDown(); + } + + /** + * No config override, no env set. + * + * @return void + */ + public function testSmtpSettingsSslOptionsGetService() + { + $result = $this->service->get(); + + $this->assertSame([], $result); + } + + public function testSmtpSettingsSslOptionsGetService_Overridden_DefaultValues() + { + Configure::write('passbolt.plugins.smtpSettings.security', [ + // default values, but in different order + 'sslCafile' => null, + 'sslVerifyPeer' => true, + 'sslVerifyPeerName' => true, + 'sslAllowSelfSigned' => false, + ]); + + $result = $this->service->get(); + + $this->assertSame([], $result); + } + + public function testSmtpSettingsSslOptionsGetService_Overridden_SpecificKeys() + { + Configure::write('passbolt.plugins.smtpSettings.security', [ + 'sslVerifyPeer' => false, + 'sslVerifyPeerName' => false, + 'sslAllowSelfSigned' => false, + ]); + + $result = $this->service->get(); + + $this->assertSame([ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'allow_self_signed' => false, + ], $result); + } + + public function testSmtpSettingsSslOptionsGetService_Overridden_CAFile() + { + Configure::write('passbolt.plugins.smtpSettings.security', [ + 'sslAllowSelfSigned' => true, + 'sslCafile' => '/path/to/cafile.crt', + ]); + + $result = $this->service->get(); + + $this->assertSame([ + 'allow_self_signed' => true, + 'cafile' => '/path/to/cafile.crt', + ], $result); + } + + public function testSmtpSettingsSslOptionsGetService_Overridden_AllValues() + { + Configure::write('passbolt.plugins.smtpSettings.security', [ + 'sslVerifyPeer' => false, + 'sslVerifyPeerName' => false, + 'sslAllowSelfSigned' => true, + 'sslCafile' => '/etc/ssl/certs/mailpit/cert.pem', + ]); + + $result = $this->service->get(); + + $this->assertSame([ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'allow_self_signed' => true, + 'cafile' => '/etc/ssl/certs/mailpit/cert.pem', + ], $result); + } +} diff --git a/plugins/PassboltCe/TotpResourceTypes/tests/TestCase/Controller/ResourceTypes/ResourceTypesIndexControllerTest.php b/plugins/PassboltCe/TotpResourceTypes/tests/TestCase/Controller/ResourceTypes/ResourceTypesIndexControllerTest.php index 89fb444a74..a4cd69cc90 100644 --- a/plugins/PassboltCe/TotpResourceTypes/tests/TestCase/Controller/ResourceTypes/ResourceTypesIndexControllerTest.php +++ b/plugins/PassboltCe/TotpResourceTypes/tests/TestCase/Controller/ResourceTypes/ResourceTypesIndexControllerTest.php @@ -31,6 +31,13 @@ class ResourceTypesIndexControllerTest extends AppIntegrationTestCase { use ResourceTypesModelTrait; + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(TotpResourceTypesPlugin::class); + $this->enableFeaturePlugin(ResourceTypesPlugin::class); + } + public function testResourceTypesIndex_Success_WithTotpResourceTypes() { $this->loadFixtureScenario(ResourceTypesScenario::class); diff --git a/plugins/PassboltCe/TotpResourceTypes/tests/TestCase/Controller/Settings/SettingsIndexControllerTest.php b/plugins/PassboltCe/TotpResourceTypes/tests/TestCase/Controller/Settings/SettingsIndexControllerTest.php index c0b3b02e46..5b7fcdcd17 100644 --- a/plugins/PassboltCe/TotpResourceTypes/tests/TestCase/Controller/Settings/SettingsIndexControllerTest.php +++ b/plugins/PassboltCe/TotpResourceTypes/tests/TestCase/Controller/Settings/SettingsIndexControllerTest.php @@ -18,9 +18,18 @@ namespace Passbolt\TotpResourceTypes\Test\TestCase\Controller\Settings; use App\Test\Lib\AppIntegrationTestCase; +use Passbolt\ResourceTypes\ResourceTypesPlugin; +use Passbolt\TotpResourceTypes\TotpResourceTypesPlugin; class SettingsIndexControllerTest extends AppIntegrationTestCase { + public function setUp(): void + { + parent::setUp(); + $this->enableFeaturePlugin(TotpResourceTypesPlugin::class); + $this->enableFeaturePlugin(ResourceTypesPlugin::class); + } + public function testSettingsIndexController_SuccessAsLU() { $this->logInAsUser(); diff --git a/plugins/PassboltCe/WebInstaller/src/Controller/SystemCheckController.php b/plugins/PassboltCe/WebInstaller/src/Controller/SystemCheckController.php index c56bf1f9e5..d935c5a372 100644 --- a/plugins/PassboltCe/WebInstaller/src/Controller/SystemCheckController.php +++ b/plugins/PassboltCe/WebInstaller/src/Controller/SystemCheckController.php @@ -16,56 +16,104 @@ */ namespace Passbolt\WebInstaller\Controller; -use App\Utility\Healthchecks; +use App\Service\Healthcheck\Environment\NextMinPhpVersionHealthcheck; +use App\Service\Healthcheck\Gpg\HomeVariableDefinedGpgHealthcheck; +use App\Service\Healthcheck\Gpg\HomeVariableWritableGpgHealthcheck; +use App\Service\Healthcheck\Gpg\PhpGpgModuleInstalledGpgHealthcheck; +use App\Service\Healthcheck\HealthcheckServiceCollector; +use App\Service\Healthcheck\HealthcheckServiceInterface; +use App\Service\Healthcheck\Ssl\IsRequestHttpsSslHealthcheck; +use Cake\Collection\Collection; +use Cake\Collection\CollectionInterface; use Cake\Routing\Router; -use Passbolt\WebInstaller\Utility\WebInstallerHealthchecks; class SystemCheckController extends WebInstallerController { /** * Index * + * @param \App\Service\Healthcheck\HealthcheckServiceCollector $healthcheckServiceCollector healthcheck service collector. * @return void */ - public function index() + public function index(HealthcheckServiceCollector $healthcheckServiceCollector) { - $checks = Healthchecks::environment(); - $gpgChecks = Healthchecks::gpg(); - $webInstallerCheck = WebInstallerHealthchecks::all(); - $checks = array_merge($checks, $gpgChecks, $webInstallerCheck); - $checks['ssl'] = ['is' => $this->request->is('ssl')]; - $checks['system_ok'] = $this->_healthcheckIsOk($checks); + $systemCheckHealthcheckServices = $this->getSystemCheckHealthcheckServices($healthcheckServiceCollector); + + $resultCollection = new Collection([]); + $isSystemOk = true; + $isRequestHttps = false; + foreach ($systemCheckHealthcheckServices as $healthcheckService) { + $result = $healthcheckService->check(); + + $resultCollection = $resultCollection->appendItem($result); + if ($healthcheckService instanceof NextMinPhpVersionHealthcheck) { + continue; + } + if ($healthcheckService instanceof IsRequestHttpsSslHealthcheck) { + $isRequestHttps = $result->isPassed(); + continue; + } + $isSystemOk = $isSystemOk && $result->isPassed(); + } + + $isNextMinPhpVersionPassed = $this->isNextMinPhpVersionPassed($resultCollection); + $environmentChecks = $resultCollection->filter(function (HealthcheckServiceInterface $result) { + return $result->domain() === HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + }); + $gpgChecks = $resultCollection->filter(function (HealthcheckServiceInterface $result) { + return $result->domain() === HealthcheckServiceCollector::DOMAIN_GPG; + }); $nextStepUrl = Router::url('/install/database', true); $this->webInstaller->setSettingsAndSave('initialized', true); - $this->set('data', $checks); - $this->set('nextStepUrl', $nextStepUrl); + $this->set(compact( + 'environmentChecks', + 'gpgChecks', + 'isNextMinPhpVersionPassed', + 'isSystemOk', + 'isRequestHttps', + 'nextStepUrl' + )); $this->render('Pages/system_check'); } /** - * Check if healthcheck values are good enough to continue installation. + * Filter all the healthcheck services to extract only the ones relevant here * - * @param array $checks checks - * @return bool + * @param \App\Service\Healthcheck\HealthcheckServiceCollector $healthcheckServiceCollector healthcheck service collector + * @return \App\Service\Healthcheck\HealthcheckServiceInterface[] */ - protected function _healthcheckIsOk($checks) + private function getSystemCheckHealthcheckServices(HealthcheckServiceCollector $healthcheckServiceCollector): array { - // Do not block installation if this check fails - unset($checks['environment']['nextMinPhpVersion']); + $domainsIncluded = [ + HealthcheckServiceCollector::DOMAIN_ENVIRONMENT, + ]; + $servicesIncluded = [ + PhpGpgModuleInstalledGpgHealthcheck::class, + HomeVariableDefinedGpgHealthcheck::class, + HomeVariableWritableGpgHealthcheck::class, + IsRequestHttpsSslHealthcheck::class, + ]; - $envCheckResults = array_values($checks['environment']); + return $healthcheckServiceCollector->getServicesFiltered($domainsIncluded, $servicesIncluded); + } + + /** + * @param \Cake\Collection\CollectionInterface $resultCollection Result collection. + * @return bool + */ + private function isNextMinPhpVersionPassed(CollectionInterface $resultCollection): bool + { + $result = false; + /** @var \App\Service\Healthcheck\HealthcheckServiceInterface $healthcheckResult */ + foreach ($resultCollection as $healthcheckResult) { + if ($healthcheckResult instanceof NextMinPhpVersionHealthcheck) { + $result = $healthcheckResult->isPassed(); - $webInstallerChecksResults = array_values($checks['webInstaller']); - $gpgKeys = ['lib', 'gpgHome', 'gpgHomeWritable']; - $gpgChecks = []; - foreach ($gpgKeys as $gpgKey) { - $gpgChecks[$gpgKey] = $checks['gpg'][$gpgKey]; + break; + } } - $gpgCheckResults = array_values($gpgChecks); - $allChecks = array_merge($envCheckResults, $gpgCheckResults, $webInstallerChecksResults); - sort($allChecks); - return $allChecks[0] ? true : false; + return $result; } } diff --git a/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PassboltConfigWritableWebInstallerHealthcheck.php b/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PassboltConfigWritableWebInstallerHealthcheck.php new file mode 100644 index 0000000000..d7d4af85d5 --- /dev/null +++ b/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PassboltConfigWritableWebInstallerHealthcheck.php @@ -0,0 +1,117 @@ +status = file_exists($passboltConfigPath) + ? is_writable($passboltConfigPath) + : $configFolderWritable; + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The passbolt config is writable.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The passbolt config is not writable.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Ensure the file ' . CONFIG . 'passbolt.php is writable by the webserver user.'), + __('you can try:'), + 'sudo chown ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . CONFIG, + 'sudo chmod 775 $(find ' . CONFIG . ' -type d)', + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'passboltConfigWritable'; + } +} diff --git a/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PrivateKeyWritableWebInstallerHealthcheck.php b/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PrivateKeyWritableWebInstallerHealthcheck.php new file mode 100644 index 0000000000..442ecdaa16 --- /dev/null +++ b/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PrivateKeyWritableWebInstallerHealthcheck.php @@ -0,0 +1,94 @@ +getPrivateServerKey())); + $privateKeyPath = $this->getPrivateServerKey(); + $this->status = file_exists($privateKeyPath) ? is_writable($privateKeyPath) : $keyFolderWritable; + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The server OpenPGP private key file is writable.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The server OpenPGP private key file is not writable.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + $privateKeyPath = $this->getPrivateServerKey(); + + return [ + __('Ensure the file {0} is writable by the webserver user.', CONFIG . 'gpg' . DS . $privateKeyPath), + __('you can try:'), + 'sudo chown ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . CONFIG . 'gpg', + 'sudo chmod 775 $(find ' . CONFIG . 'gpg -type d)', + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'privateKeyWritable'; + } +} diff --git a/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PublicKeyWritableWebInstallerHealthcheck.php b/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PublicKeyWritableWebInstallerHealthcheck.php new file mode 100644 index 0000000000..3e62926982 --- /dev/null +++ b/plugins/PassboltCe/WebInstaller/src/Service/Healthcheck/PublicKeyWritableWebInstallerHealthcheck.php @@ -0,0 +1,94 @@ +getPublicServerKey())); + $publicKeyPath = $this->getPublicServerKey(); + $this->status = file_exists($publicKeyPath) ? is_writable($publicKeyPath) : $keyFolderWritable; + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The server OpenPGP public key file is writable.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The server OpenPGP public key file is not writable.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + $publicKeyPath = $this->getPublicServerKey(); + + return [ + __('Ensure the file {0} is writable by the webserver user.', CONFIG . 'gpg' . DS . $publicKeyPath), + __('you can try:'), + 'sudo chown ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . CONFIG . 'gpg', + 'sudo chmod 775 $(find ' . CONFIG . 'gpg -type d)', + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'publicKeyWritable'; + } +} diff --git a/plugins/PassboltCe/WebInstaller/src/Utility/DatabaseConfiguration.php b/plugins/PassboltCe/WebInstaller/src/Utility/DatabaseConfiguration.php index aff59fd743..6342e96c72 100644 --- a/plugins/PassboltCe/WebInstaller/src/Utility/DatabaseConfiguration.php +++ b/plugins/PassboltCe/WebInstaller/src/Utility/DatabaseConfiguration.php @@ -16,7 +16,6 @@ */ namespace Passbolt\WebInstaller\Utility; -use App\Utility\Healthchecks; use Cake\Core\Exception\CakeException; use Cake\Database\Connection; use Cake\Database\Driver\Mysql; @@ -82,7 +81,7 @@ public static function testConnection(): bool } try { - $connection->connect(); + $connection->getDriver()->connect(); return true; } catch (\Throwable $e) { @@ -111,11 +110,49 @@ public static function getTables() public static function validateSchema() { $tables = self::getTables(); - $expectedTables = Healthchecks::getSchemaTables(1); + $expectedTables = self::getSchemaTables(1); foreach ($expectedTables as $expectedTable) { if (!in_array($expectedTable, $tables)) { throw new CakeException(__('The database schema does not match the one expected')); } } } + + /** + * Get schema tables list. (per version number). + * + * @param int $version passbolt major version number. + * @return array + */ + public static function getSchemaTables(int $version = 2): array + { + // List of tables for passbolt v1. + $tables = [ + 'authentication_tokens', + 'avatars', + 'comments', + 'email_queue', + 'favorites', + 'gpgkeys', + 'groups', + 'groups_users', + 'permissions', + 'profiles', + 'resources', + 'roles', + 'secrets', + 'users', + ]; + + // Extra tables for passbolt v2. + if ($version == 2) { + $tables = array_merge($tables, [ + //'burzum_file_storage_phinxlog', // dropped in v2.8 + //'email_queue_phinxlog', + 'phinxlog', + ]); + } + + return $tables; + } } diff --git a/plugins/PassboltCe/WebInstaller/src/Utility/WebInstallerHealthchecks.php b/plugins/PassboltCe/WebInstaller/src/Utility/WebInstallerHealthchecks.php deleted file mode 100644 index 1682426c98..0000000000 --- a/plugins/PassboltCe/WebInstaller/src/Utility/WebInstallerHealthchecks.php +++ /dev/null @@ -1,63 +0,0 @@ -assert( - $checks['webInstaller']['passboltConfigWritable'], - __('The passbolt config is writable.'), - __('The passbolt config is not writable.'), - [ - __('Ensure the file ' . CONFIG . 'passbolt.php is writable by the webserver user.'), - __('you can try:'), - 'sudo chown ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . CONFIG, - 'sudo chmod 775 $(find ' . CONFIG . ' -type d)', - ] - ); - - $publicKeyPath = Configure::read('passbolt.gpg.serverKey.public'); - $this->assert( - $checks['webInstaller']['publicKeyWritable'], - __('The server OpenPGP public key file is writable.'), - __('The server OpenPGP public key file is not writable.'), - [ - __('Ensure the file {0} is writable by the webserver user.', CONFIG . 'gpg' . DS . $publicKeyPath), - __('you can try:'), - 'sudo chown ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . CONFIG . 'gpg', - 'sudo chmod 775 $(find ' . CONFIG . 'gpg -type d)', - ] - ); - - $privateKeyPath = Configure::read('passbolt.gpg.serverKey.private'); - $this->assert( - $checks['webInstaller']['privateKeyWritable'], - __('The server OpenPGP private key file is writable.'), - __('The server OpenPGP private key file is not writable.'), - [ - __('Ensure the file {0} is writable by the webserver user.', CONFIG . 'gpg' . DS . $privateKeyPath), - __('you can try:'), - 'sudo chown ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . CONFIG . 'gpg', - 'sudo chmod 775 $(find ' . CONFIG . 'gpg -type d)', - ] - ); - } -} diff --git a/plugins/PassboltCe/WebInstaller/src/WebInstallerPlugin.php b/plugins/PassboltCe/WebInstaller/src/WebInstallerPlugin.php index e2489250f9..40662622d1 100644 --- a/plugins/PassboltCe/WebInstaller/src/WebInstallerPlugin.php +++ b/plugins/PassboltCe/WebInstaller/src/WebInstallerPlugin.php @@ -16,10 +16,15 @@ */ namespace Passbolt\WebInstaller; +use App\Service\Healthcheck\HealthcheckServiceCollector; +use App\Service\Healthcheck\Ssl\IsRequestHttpsSslHealthcheck; use Cake\Core\BasePlugin; use Cake\Core\ContainerInterface; use Cake\Http\MiddlewareQueue; use Passbolt\WebInstaller\Middleware\WebInstallerMiddleware; +use Passbolt\WebInstaller\Service\Healthcheck\PassboltConfigWritableWebInstallerHealthcheck; +use Passbolt\WebInstaller\Service\Healthcheck\PrivateKeyWritableWebInstallerHealthcheck; +use Passbolt\WebInstaller\Service\Healthcheck\PublicKeyWritableWebInstallerHealthcheck; use Passbolt\WebInstaller\Service\WebInstallerChangeConfigFolderPermissionService; class WebInstallerPlugin extends BasePlugin @@ -43,5 +48,16 @@ public function services(ContainerInterface $container): void WebInstallerChangeConfigFolderPermissionService::class ) ->addArgument(CONFIG); + + $container->add(PassboltConfigWritableWebInstallerHealthcheck::class); + $container->add(PublicKeyWritableWebInstallerHealthcheck::class); + $container->add(PrivateKeyWritableWebInstallerHealthcheck::class); + + $container + ->extend(HealthcheckServiceCollector::class) + ->addMethodCall('addService', [PassboltConfigWritableWebInstallerHealthcheck::class]) + ->addMethodCall('addService', [PublicKeyWritableWebInstallerHealthcheck::class]) + ->addMethodCall('addService', [PrivateKeyWritableWebInstallerHealthcheck::class]) + ->addMethodCall('addService', [IsRequestHttpsSslHealthcheck::class]); } } diff --git a/plugins/PassboltCe/WebInstaller/templates/Pages/system_check.php b/plugins/PassboltCe/WebInstaller/templates/Pages/system_check.php index 038c00cb93..02d6d94286 100644 --- a/plugins/PassboltCe/WebInstaller/templates/Pages/system_check.php +++ b/plugins/PassboltCe/WebInstaller/templates/Pages/system_check.php @@ -3,12 +3,18 @@ /** * @var \App\View\AppView $this - * @var array $data + * @var bool $isSystemOk + * @var bool $isNextMinPhpVersionPassed + * @var bool $isRequestHttps * @var string $nextStepUrl + * @var \Cake\Collection\Collection $environmentChecks + * @var \Cake\Collection\Collection $gpgChecks */ -use Passbolt\WebInstaller\View\Helper\HealthcheckHtmlHelper; -$healtcheck = new HealthcheckHtmlHelper(); +use App\View\Helper\HealthcheckHtmlHelper; + +$healthcheckHelper = new HealthcheckHtmlHelper(); + ?> element('header', ['title' => __('Welcome to Passbolt! Let\'s get started with the configuration.')]) ?>
@@ -22,56 +28,68 @@
-

- ' . __('Nice one! Your environment is ready for passbolt.') . ''; else : - ?> -

- ' . __('Oops!! Passbolt cannot run yet on your server.') . ''; endif; ?> + Flash->render() ?> + assertEnvironment($data); - } elseif ($data['system_ok'] && !$data['environment']['nextMinPhpVersion']) { - $healtcheck->assertEnvironment($data); + /** + * Display environment domain results. + */ + // We want display the warning when php version is less than next minimum PHP version we'll support. + // That's why this complex condition :) + if (!$isSystemOk || ($isSystemOk && !$isNextMinPhpVersionPassed)) { + echo '

Environment

'; + foreach ($environmentChecks as $checkResult) { + $healthcheckHelper->render($checkResult); + } } else { + // Environment is fine echo '
' . __('Environment is configured correctly.') . '
'; } ?> + ' . __('GPG is configured correctly.') . '
'; } else { echo '

' . __('GPG Configuration') . '

'; - $healtcheck->assertGpgEnv($data); + foreach ($gpgChecks as $domain => $checkResult) { + $healthcheckHelper->render($checkResult); + } } ?> -

- + ' . __('SSL access is enabled.') . '
'; else : echo '
' . __('SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue.') . '
'; endif; ?>
+
element('sidebar/help_box') ?>
@@ -79,7 +97,7 @@
diff --git a/plugins/PassboltCe/WebInstaller/tests/Lib/WebInstallerIntegrationTestCase.php b/plugins/PassboltCe/WebInstaller/tests/Lib/WebInstallerIntegrationTestCase.php index 73fca2bfa1..cdf936fb15 100644 --- a/plugins/PassboltCe/WebInstaller/tests/Lib/WebInstallerIntegrationTestCase.php +++ b/plugins/PassboltCe/WebInstaller/tests/Lib/WebInstallerIntegrationTestCase.php @@ -40,7 +40,6 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); if ($this->_recover) { if ($this->_configured !== null) { Configure::write('passbolt.webInstaller.configured', $this->_configured); @@ -51,6 +50,7 @@ public function tearDown(): void if ($this->isWebInstallerFriendly()) { $this->restoreTestConnection(); } + parent::tearDown(); } public function mockPassboltIsNotconfigured() diff --git a/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/DatabaseControllerTest.php b/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/DatabaseControllerTest.php index f0aa7797ad..9cb353c82d 100644 --- a/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/DatabaseControllerTest.php +++ b/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/DatabaseControllerTest.php @@ -30,8 +30,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); $this->restoreTestConnection(); + parent::tearDown(); } public function testDatabaseControllerViewSuccess() diff --git a/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/InstallationControllerTest.php b/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/InstallationControllerTest.php index fc1df6428c..422e6ac37f 100644 --- a/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/InstallationControllerTest.php +++ b/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/InstallationControllerTest.php @@ -21,7 +21,6 @@ use App\Utility\Filesystem\DirectoryUtility; use Cake\Core\Configure; use Cake\Datasource\ConnectionManager; -use Cake\ORM\TableRegistry; use Cake\Validation\Validation; use Passbolt\WebInstaller\Form\DatabaseConfigurationForm; use Passbolt\WebInstaller\Service\WebInstallerChangeConfigFolderPermissionService; @@ -40,7 +39,6 @@ public function setUp(): void public function tearDown(): void { $this->restoreConfiguration(); - TableRegistry::getTableLocator()->clear(); parent::tearDown(); } diff --git a/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/SystemCheckControllerTest.php b/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/SystemCheckControllerTest.php index 9e1b17a235..9d79fcf71d 100644 --- a/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/SystemCheckControllerTest.php +++ b/plugins/PassboltCe/WebInstaller/tests/TestCase/Controller/SystemCheckControllerTest.php @@ -16,8 +16,13 @@ */ namespace Passbolt\WebInstaller\Test\TestCase\Controller; -use App\Utility\Healthchecks; +use App\Service\Healthcheck\Environment\NextMinPhpVersionHealthcheck; +use App\Service\Healthcheck\Environment\PhpVersionHealthcheck; use Cake\Core\Configure; +use Cake\Http\ServerRequest; +use Passbolt\WebInstaller\Service\Healthcheck\PassboltConfigWritableWebInstallerHealthcheck; +use Passbolt\WebInstaller\Service\Healthcheck\PrivateKeyWritableWebInstallerHealthcheck; +use Passbolt\WebInstaller\Service\Healthcheck\PublicKeyWritableWebInstallerHealthcheck; use Passbolt\WebInstaller\Test\Lib\WebInstallerIntegrationTestCase; class SystemCheckControllerTest extends WebInstallerIntegrationTestCase @@ -28,6 +33,21 @@ public function setUp(): void $this->skipTestIfNotWebInstallerFriendly(); $this->mockPassboltIsNotconfigured(); $this->initWebInstallerSession(); + $this->mockService(ServerRequest::class, function () { + return (new ServerRequest())->withEnv('HTTPS', 'on'); + }); + $this->mockService(PhpVersionHealthcheck::class, function () { + $stub = $this->getMockBuilder(PhpVersionHealthcheck::class)->onlyMethods(['isPassed'])->getMock(); + $stub->method('isPassed')->willReturn(true); + + return $stub; + }); + $this->mockService(NextMinPhpVersionHealthcheck::class, function () { + $stub = $this->getMockBuilder(NextMinPhpVersionHealthcheck::class)->onlyMethods(['isPassed'])->getMock(); + $stub->method('isPassed')->willReturn(true); + + return $stub; + }); } /** @@ -36,62 +56,106 @@ public function setUp(): void public function testWebInstallerSystemCheckViewSuccess() { $this->get('/install/system_check'); + $this->assertCanStartSetup(); + + $this->assertResponseContains('1. System check'); + $this->assertResponseContains('
Environment is configured correctly.
'); + $this->assertResponseContains('
GPG is configured correctly.
'); + $this->assertResponseContains('
SSL access is enabled.
'); + } - $data = $this->_getBodyAsString(); + public function testWebInstallerSystemCheck_Ssl_Off() + { + $this->mockService(ServerRequest::class, function () { + return (new ServerRequest())->withEnv('HTTPS', 'off'); + }); - $this->assertResponseOk(); - $minPhpVersion = Configure::read(Healthchecks::PHP_MIN_VERSION_CONFIG); - $nextMinPhpVersion = Configure::read(Healthchecks::PHP_NEXT_MIN_VERSION_CONFIG); - if (version_compare(PHP_VERSION, $minPhpVersion, '<')) { - $this->assertStringContainsString('PHP version is too low', $data); - } elseif ( - version_compare(PHP_VERSION, $minPhpVersion, '>=') - && version_compare(PHP_VERSION, $nextMinPhpVersion, '<=') - ) { - // Warning is shown to user - $this->assertStringContainsString( - __( - 'PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment', // phpcs:ignore - $nextMinPhpVersion - ), - $data - ); - // User can continue with the installation - $this->assertStringContainsString('Nice one! Your environment is ready for passbolt.', $data); - $this->assertStringContainsString('GPG is configured correctly.', $data); - $this->assertStringContainsString('Start configuration', $data); - } else { - $this->assertStringContainsString('. Database', $data); - $this->assertStringContainsString('Nice one! Your environment is ready for passbolt.', $data); - $this->assertStringContainsString('Environment is configured correctly.', $data); - $this->assertStringContainsString('GPG is configured correctly.', $data); - $this->assertStringContainsString('Start configuration', $data); + $this->get('/install/system_check'); + + $this->assertCanStartSetup(); + $this->assertResponseContains('
SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue.
'); + } + + public function testWebInstallerSystemCheck_PHP_Version_Too_Low() + { + $this->mockFailingHealthcheck(PhpVersionHealthcheck::class); + + $this->get('/install/system_check'); + + $this->assertCannotStartSetup(); + $this->assertResponseContains('
PHP version is too'); + } + + public function testWebInstallerSystemCheck_PHP_Below_Next_Version_Warning() + { + $this->mockFailingHealthcheck(NextMinPhpVersionHealthcheck::class); + + $this->get('/install/system_check'); + + $this->assertCanStartSetup(); + $msg = 'PHP version less than ' . Configure::read(NextMinPhpVersionHealthcheck::PHP_NEXT_MIN_VERSION_CONFIG) . ' will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment.'; // phpcs:ignore + $this->assertResponseContains('
' . $msg); + $this->assertResponseNotContains('Environment is configured correctly.'); + $this->assertResponseContains('GPG is configured correctly.'); + } + + public function testWebInstallerSystemCheck_WebInstallerChecksFailing() + { + $servicesToMock = [ + PassboltConfigWritableWebInstallerHealthcheck::class, + PublicKeyWritableWebInstallerHealthcheck::class, + PrivateKeyWritableWebInstallerHealthcheck::class, + ]; + foreach ($servicesToMock as $service) { + $this->mockFailingHealthcheck($service); } + + $this->get('/install/system_check'); + + $this->assertResponseContains('

Environment

'); + $this->assertResponseContains('

GPG Configuration

'); + $this->assertResponseContains('

SSL

'); + $this->assertResponseContains('
The server OpenPGP public key file is not writable.
'); + $this->assertResponseContains('
The server OpenPGP private key file is not writable.
'); + $this->assertResponseContains('
The passbolt config is not writable.
'); + $this->assertCannotStartSetup(); } - /** - * note: creates an issue with healthcheck on a webserverless environment. - */ - public function testWebInstallerSystemCheckViewSuccess_LicensePluginEnabled() + public function testWebInstallerSystemCheck_Gpg_Directory_Undefined() { + Configure::write('passbolt.gpg.backend', 'foo'); + $this->get('/install/system_check'); - $data = $this->_getBodyAsString(); + $this->assertResponseContains('

Environment

'); + $this->assertResponseContains('

GPG Configuration

'); + $this->assertResponseContains('

SSL

'); + $this->assertResponseContains('
PHP GPG Module is not installed or loaded.
'); + $this->assertResponseContains('
The environment variable GNUPGHOME is set to , but the directory does not exist.
'); + $this->assertResponseContains('
The directory containing the keyring is not writable by the webserver user.
'); + $this->assertCannotStartSetup(); + } + + private function assertCanStartSetup(): void + { $this->assertResponseOk(); - $minPhpVersion = Configure::read(Healthchecks::PHP_MIN_VERSION_CONFIG); - $nextMinPhpVersion = Configure::read(Healthchecks::PHP_NEXT_MIN_VERSION_CONFIG); - if (version_compare(PHP_VERSION, $minPhpVersion, '<')) { - $this->assertStringContainsString('PHP version is too low', $data); - } elseif (version_compare(PHP_VERSION, $nextMinPhpVersion, '<=')) { - $this->assertStringContainsString( - __( - 'PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment', // phpcs:ignore - $nextMinPhpVersion - ), - $data - ); - } else { - $this->assertStringContainsString('Start configuration', $data); - } + $this->assertResponseContains('Nice one! Your environment is ready for passbolt.'); + $this->assertResponseContains('Start configuration'); + } + + private function assertCannotStartSetup(): void + { + $this->assertResponseOk(); + $this->assertResponseContains('Oops!! Passbolt cannot run yet on your server.'); + } + + private function mockFailingHealthcheck(string $service): void + { + $this->mockService($service, function () use ($service) { + $stub = $this->getMockBuilder($service)->onlyMethods(['isPassed'])->getMock(); + $stub->method('isPassed')->willReturn(false); + + return $stub; + }); } } diff --git a/plugins/PassboltCe/WebInstaller/tests/TestCase/Utility/WebInstallerTest.php b/plugins/PassboltCe/WebInstaller/tests/TestCase/Utility/WebInstallerTest.php index 19fbbe9e0b..9576223192 100644 --- a/plugins/PassboltCe/WebInstaller/tests/TestCase/Utility/WebInstallerTest.php +++ b/plugins/PassboltCe/WebInstaller/tests/TestCase/Utility/WebInstallerTest.php @@ -43,8 +43,8 @@ public function setUp(): void public function tearDown(): void { - parent::tearDown(); $this->restoreConfiguration(); + parent::tearDown(); } public function testWebInstallerUtilityInitDatabaseConnectionSuccess() diff --git a/resources/locales/de_DE/default.po b/resources/locales/de_DE/default.po index ffe163596c..769f339893 100644 --- a/resources/locales/de_DE/default.po +++ b/resources/locales/de_DE/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:56\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: German\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Validierung erfolgreich für Gruppe {0}" msgid "Could not validate group user data." msgstr "Konnte die Gruppenbenutzer-Daten nicht validieren." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "undefiniert" + +msgid "Could not connect to github repository" +msgstr "Verbindung zum Github Repository fehlgeschlagen" + +msgid "Could not read tag information on github repository" +msgstr "Tag-Informationen im GitHub Repository konnten nicht gelesen werden" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "Sie können versuchen:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Datenbank" + +msgid "GPG Configuration" +msgstr "GPG-Konfiguration" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "SSL-Zugriff ist aktiviert." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "SSL-Zugriff ist nicht aktiviert. Sie können trotzdem fortfahren, aber es wird dringend empfohlen, dass Sie Ihren Webserver so konfigurieren, dass er HTTPS verwendet, bevor Sie fortfahren." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Sub-Key Data konnte nicht validiert werden." @@ -1450,15 +1981,6 @@ msgstr "Validierung erfolgreich für Benutzer*in {0}" msgid "The directory {0} cannot be deleted" msgstr "Das Verzeichnis {0} kann nicht gelöscht werden" -msgid "Database connection failed" -msgstr "Datenbankverbindung fehlgeschlagen" - -msgid "Could not connect to github repository" -msgstr "Verbindung zum Github Repository fehlgeschlagen" - -msgid "Could not read tag information on github repository" -msgstr "Tag-Informationen im GitHub Repository konnten nicht gelesen werden" - msgid "The key {0} cannot be used to encrypt." msgstr "Der Schlüssel {0} kann nicht zum Verschlüsseln verwendet werden." @@ -1849,6 +2371,21 @@ msgstr "Der JWT private Schlüssel sollte mindestens {0} Bytes lang sein." msgid "The configuration {0} is not correctly set." msgstr "Die Konfiguration {0} ist nicht korrekt gesetzt." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Das Aktualisierungstoken sollte eine gültige UUID sein." @@ -3034,29 +3571,53 @@ msgstr "Endpunkte der SMTP-Einstellungen deaktiviert." msgid "The client should be a valid IP or a valid domain." msgstr "Der Client sollte eine gültige IP oder Domain sein." -msgid "Could not validate the smtp settings." -msgstr "Die SMTP-Einstellungen konnten nicht validiert werden." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "Konnte die SMTP-Einstellungen in der Datenbank nicht validieren." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "Der OpenPGP-Server-Schlüssel kann nicht verwendet werden, um die in der Datenbank gespeicherten SMTP-Einstellungen zu entschlüsseln." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Um dieses Problem zu beheben, müssen Sie den SMTP-Server erneut konfigurieren." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "nicht gefunden" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "datenbank" msgid "env variables" msgstr "Umgebungsvariablen" -msgid "undefined" -msgstr "undefiniert" +msgid "Could not validate the smtp settings." +msgstr "Die SMTP-Einstellungen konnten nicht validiert werden." + +msgid "Could not validate the smtp settings found in database." +msgstr "Konnte die SMTP-Einstellungen in der Datenbank nicht validieren." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "Der OpenPGP-Server-Schlüssel kann nicht verwendet werden, um die in der Datenbank gespeicherten SMTP-Einstellungen zu entschlüsseln." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Um dieses Problem zu beheben, müssen Sie den SMTP-Server erneut konfigurieren." msgid "Passbolt test email" msgstr "Test-E-Mail von Passbolt" @@ -3088,9 +3649,6 @@ msgstr "Systemüberprüfung" msgid "Subscription key" msgstr "Abo-Schlüssel" -msgid "Database" -msgstr "Datenbank" - msgid "Server keys" msgstr "Serverschlüssel" @@ -3205,18 +3763,6 @@ msgstr "Ein Force SSL Status ist erforderlich." msgid "The force ssl setting should be a valid boolean." msgstr "Die SSL-Erzwingen Einstellung sollte ein gültiger Boolescher Wert sein." -msgid "The database schema does not match the one expected" -msgstr "Das Datenbankschema entspricht nicht dem erwarteten" - -msgid "The database cannot be installed" -msgstr "Die Datenbank kann nicht installiert werden" - -msgid "There was a problem creating the first user" -msgstr "Beim Erstellen des ersten Benutzers ist ein Problem aufgetreten" - -msgid "There was a problem creating the registration token" -msgstr "Beim Erstellen des Registrierungstokens ist ein Problem aufgetreten" - msgid "The passbolt config is writable." msgstr "Die Passbolt Konfiguration ist beschreibbar." @@ -3226,8 +3772,14 @@ msgstr "Die Passbolt Konfiguration ist nicht beschreibbar." msgid "Ensure the file " msgstr "Datei sicherstellen " -msgid "you can try:" -msgstr "Sie können versuchen:" +msgid "The server OpenPGP private key file is writable." +msgstr "Die private OpenPGP Schlüsseldatei des Servers ist schreibbar." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Die private OpenPGP Schlüsseldatei des Servers ist nicht schreibbar." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Stellen Sie sicher, dass die Datei {0} vom Benutzer des Webservers schreibbar ist." msgid "The server OpenPGP public key file is writable." msgstr "Die öffentliche OpenPGP Schlüsseldatei des Servers ist beschreibbar." @@ -3235,14 +3787,17 @@ msgstr "Die öffentliche OpenPGP Schlüsseldatei des Servers ist beschreibbar." msgid "The server OpenPGP public key file is not writable." msgstr "Die OpenPGP öffentliche Schlüsseldatei des Servers ist nicht schreibbar." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Stellen Sie sicher, dass die Datei {0} vom Benutzer des Webservers schreibbar ist." +msgid "The database schema does not match the one expected" +msgstr "Das Datenbankschema entspricht nicht dem erwarteten" -msgid "The server OpenPGP private key file is writable." -msgstr "Die private OpenPGP Schlüsseldatei des Servers ist schreibbar." +msgid "The database cannot be installed" +msgstr "Die Datenbank kann nicht installiert werden" -msgid "The server OpenPGP private key file is not writable." -msgstr "Die private OpenPGP Schlüsseldatei des Servers ist nicht schreibbar." +msgid "There was a problem creating the first user" +msgstr "Beim Erstellen des ersten Benutzers ist ein Problem aufgetreten" + +msgid "There was a problem creating the registration token" +msgstr "Beim Erstellen des Registrierungstokens ist ein Problem aufgetreten" msgid "Create your user account!" msgstr "Erstellen Sie Ihr Benutzerkonto!" @@ -3442,18 +3997,9 @@ msgstr "URL-Rewriting ist auf Ihrem Server nicht korrekt konfiguriert." msgid "GPG is configured correctly." msgstr "GPG ist korrekt konfiguriert." -msgid "GPG Configuration" -msgstr "GPG-Konfiguration" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "SSL-Zugriff ist aktiviert." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "SSL-Zugriff ist nicht aktiviert. Sie können trotzdem fortfahren, aber es wird dringend empfohlen, dass Sie Ihren Webserver so konfigurieren, dass er HTTPS verwendet, bevor Sie fortfahren." - msgid "Start configuration" msgstr "Konfiguration starten" @@ -3544,9 +4090,6 @@ msgstr "Gesundheitschecks" msgid "Passbolt API Status" msgstr "Passbolt API Status" -msgid "SSL access is not enabled." -msgstr "SSL-Zugriff ist nicht aktiviert." - msgid "Group manager" msgstr "Gruppenmanager" diff --git a/resources/locales/en_UK/default.po b/resources/locales/en_UK/default.po index 22269b228e..00933d52f6 100644 --- a/resources/locales/en_UK/default.po +++ b/resources/locales/en_UK/default.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" "Last-Translator: NAME \n" "Language-Team: LANGUAGE \n" @@ -1238,6 +1238,537 @@ msgstr "" msgid "Could not validate group user data." msgstr "" +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "" + +msgid "Could not connect to github repository" +msgstr "" + +msgid "Could not read tag information on github repository" +msgstr "" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "" + +msgid "GPG Configuration" +msgstr "" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "" + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "" + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "" @@ -1448,15 +1979,6 @@ msgstr "" msgid "The directory {0} cannot be deleted" msgstr "" -msgid "Database connection failed" -msgstr "" - -msgid "Could not connect to github repository" -msgstr "" - -msgid "Could not read tag information on github repository" -msgstr "" - msgid "The key {0} cannot be used to encrypt." msgstr "" @@ -1847,6 +2369,21 @@ msgstr "" msgid "The configuration {0} is not correctly set." msgstr "" +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "" @@ -3032,28 +3569,52 @@ msgstr "" msgid "The client should be a valid IP or a valid domain." msgstr "" -msgid "Could not validate the smtp settings." +msgid "SMTP Settings coherent. You may send a test email to validate them." msgstr "" -msgid "Could not validate the smtp settings found in database." +msgid "SMTP Setting errors: {0}" msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgid "The {0} plugin endpoints are disabled." msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." msgstr "" msgid "not found" msgstr "" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "" msgid "env variables" msgstr "" -msgid "undefined" +msgid "Could not validate the smtp settings." +msgstr "" + +msgid "Could not validate the smtp settings found in database." +msgstr "" + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "" + +msgid "To fix this problem, you need to configure the SMTP server again." msgstr "" msgid "Passbolt test email" @@ -3086,9 +3647,6 @@ msgstr "" msgid "Subscription key" msgstr "" -msgid "Database" -msgstr "" - msgid "Server keys" msgstr "" @@ -3203,28 +3761,22 @@ msgstr "" msgid "The force ssl setting should be a valid boolean." msgstr "" -msgid "The database schema does not match the one expected" -msgstr "" - -msgid "The database cannot be installed" -msgstr "" - -msgid "There was a problem creating the first user" +msgid "The passbolt config is writable." msgstr "" -msgid "There was a problem creating the registration token" +msgid "The passbolt config is not writable." msgstr "" -msgid "The passbolt config is writable." +msgid "Ensure the file " msgstr "" -msgid "The passbolt config is not writable." +msgid "The server OpenPGP private key file is writable." msgstr "" -msgid "Ensure the file " +msgid "The server OpenPGP private key file is not writable." msgstr "" -msgid "you can try:" +msgid "Ensure the file {0} is writable by the webserver user." msgstr "" msgid "The server OpenPGP public key file is writable." @@ -3233,13 +3785,16 @@ msgstr "" msgid "The server OpenPGP public key file is not writable." msgstr "" -msgid "Ensure the file {0} is writable by the webserver user." +msgid "The database schema does not match the one expected" msgstr "" -msgid "The server OpenPGP private key file is writable." +msgid "The database cannot be installed" msgstr "" -msgid "The server OpenPGP private key file is not writable." +msgid "There was a problem creating the first user" +msgstr "" + +msgid "There was a problem creating the registration token" msgstr "" msgid "Create your user account!" @@ -3440,18 +3995,9 @@ msgstr "" msgid "GPG is configured correctly." msgstr "" -msgid "GPG Configuration" -msgstr "" - msgid "SSL" msgstr "" -msgid "SSL access is enabled." -msgstr "" - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "" - msgid "Start configuration" msgstr "" @@ -3542,9 +4088,6 @@ msgstr "" msgid "Passbolt API Status" msgstr "" -msgid "SSL access is not enabled." -msgstr "" - msgid "Group manager" msgstr "" diff --git a/resources/locales/es_ES/default.po b/resources/locales/es_ES/default.po index fdefa86523..08a1890263 100644 --- a/resources/locales/es_ES/default.po +++ b/resources/locales/es_ES/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:56\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-26 16:44\n" "Last-Translator: NAME \n" "Language-Team: Spanish\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Validación correcta para el grupo {0}" msgid "Could not validate group user data." msgstr "No se pudo validar los datos del grupo de usuarios." +msgid "All email notifications will be sent." +msgstr "Se enviarán todas las notificaciones de correo electrónico." + +msgid "Some email notifications are disabled by the administrator." +msgstr "Algunas notificaciones de correo electrónico están desactivadas por el administrador." + +msgid "Host availability will be checked." +msgstr "Se comprobará la disponibilidad del host." + +msgid "Host availability checking is disabled." +msgstr "La comprobación de disponibilidad del host está desactivada." + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "sin definir" + +msgid "Could not connect to github repository" +msgstr "No se pudo conectar al repositorio github" + +msgid "Could not read tag information on github repository" +msgstr "No se pudo leer la información de etiquetas en el repositorio github" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "Copiar {0} a {1}" + +msgid "The passbolt config file is present" +msgstr "El archivo de configuración de Passbolt está presente" + +msgid "The passbolt config file is missing in {0}" +msgstr "Falta el archivo de configuración de Passbolt en {0}" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "El archivo de configuración de Passbolt no es necesario si Passbolt está configurado con variables de entorno" + +msgid "Cache is working." +msgstr "La caché está funcionando." + +msgid "Cache is NOT working." +msgstr "La caché NO está funcionando." + +msgid "Check the settings in {0}" +msgstr "Compruebe la configuración en {0}" + +msgid "Debug mode is off." +msgstr "Modo de depuración desactivado." + +msgid "Debug mode is on." +msgstr "Modo de depuración activado." + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "La URL base completa se ha establecido a {0}" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "{0} tablas encontradas." + +msgid "No table found." +msgstr "No se han encontrado tablas." + +msgid "GD or Imagick extension is installed." +msgstr "La extensión GD o Imagick está instalada." + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "Debe habilitar las extensiones GD o Imagick para usar Passbolt." + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "Vea https://secure.php.net/manual/es/book.image.php" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "Vea https://secure.php.net/manual/es/book.imagick.php" + +msgid "Intl extension is installed." +msgstr "La extensión Intl está instalada." + +msgid "You must enable the intl extension to use Passbolt." +msgstr "Debe habilitar la extensión Intl para usar Passbolt." + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "Vea https://secure.php.net/manual/es/book.intl.php" + +msgid "The logs directory and its content are writable." +msgstr "El directorio de logs y su contenido tienen permisos de escritura." + +msgid "The logs directory and its content are not writable." +msgstr "El directorio de logs y su contenido no tienen permisos de escritura." + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "Asegúrese de que el usuario del servidor web tiene permisos de escritura en el directorio de registros y su contenido." + +msgid "you can try:" +msgstr "puedes probar:" + +msgid "Mbstring extension is installed." +msgstr "La extensión Mbstring está instalada." + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "Debe habilitar la extensión Mbstring para usar Passbolt." + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "Vea https://secure.php.net/manual/es/book.mbstring.php" + +msgid "PHP version is {0} or above." +msgstr "La versión de PHP es {0} o superior." + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "Las versiones de PHP menores que {0} pronto dejarán de ser compatibles con Passbolt, así que considere actualizar su sistema operativo o entorno PHP." + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "Versión de PHP {0}." + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "La versión de PHP es demasiado baja, Passbolt necesita PHP {0} o superior." + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Base de datos" + +msgid "GPG Configuration" +msgstr "Configuración GPG" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "El acceso SSL está habilitado." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "El acceso SSL no está habilitado. Todavía puede continuar, pero es altamente recomendable que configure su servidor web para que use HTTPS antes de continuar." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "No se pudieron validar los datos de la sub-clave." @@ -1450,15 +1981,6 @@ msgstr "Validación correcta para el usuario {0}" msgid "The directory {0} cannot be deleted" msgstr "No se puede eliminar el directorio {0}" -msgid "Database connection failed" -msgstr "La conexión con la base de datos ha fallado" - -msgid "Could not connect to github repository" -msgstr "No se pudo conectar al repositorio github" - -msgid "Could not read tag information on github repository" -msgstr "No se pudo leer la información de etiquetas en el repositorio github" - msgid "The key {0} cannot be used to encrypt." msgstr "La clave {0} no se puede usar para encriptar." @@ -1849,6 +2371,21 @@ msgstr "La clave privada JWT debe tener al menos {0} bytes de longitud." msgid "The configuration {0} is not correctly set." msgstr "La configuración {0} no está establecida correctamente." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "El token de actualización debe ser un UUID válido." @@ -3034,29 +3571,53 @@ msgstr "Endpoints de configuración SMTP desactivados." msgid "The client should be a valid IP or a valid domain." msgstr "El cliente debe ser una IP válida o un dominio válido." -msgid "Could not validate the smtp settings." -msgstr "No se ha podido validar la configuración SMTP." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "No se han podido validar los ajustes SMTP encontrados en la base de datos." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "No se puede usar la clave OpenPGP del servidor para descifrar la configuración SMTP almacenada en la base de datos." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Para solucionar este problema, necesita configurar el servidor SMTP de nuevo." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "no se ha encontrado" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "base de datos" msgid "env variables" msgstr "variables de entorno" -msgid "undefined" -msgstr "sin definir" +msgid "Could not validate the smtp settings." +msgstr "No se ha podido validar la configuración SMTP." + +msgid "Could not validate the smtp settings found in database." +msgstr "No se han podido validar los ajustes SMTP encontrados en la base de datos." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "No se puede usar la clave OpenPGP del servidor para descifrar la configuración SMTP almacenada en la base de datos." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Para solucionar este problema, necesita configurar el servidor SMTP de nuevo." msgid "Passbolt test email" msgstr "Correo electrónico de prueba de Passbolt" @@ -3088,9 +3649,6 @@ msgstr "Comprobación del sistema" msgid "Subscription key" msgstr "Clave de suscripción" -msgid "Database" -msgstr "Base de datos" - msgid "Server keys" msgstr "Claves del servidor" @@ -3205,18 +3763,6 @@ msgstr "Se requiere un estado ssl forzado." msgid "The force ssl setting should be a valid boolean." msgstr "La configuración de forzar ssl debe ser un booleano válido." -msgid "The database schema does not match the one expected" -msgstr "El esquema de base de datos no coincide con el esperado" - -msgid "The database cannot be installed" -msgstr "No se puede instalar la base de datos" - -msgid "There was a problem creating the first user" -msgstr "Hubo un problema al crear el primer usuario" - -msgid "There was a problem creating the registration token" -msgstr "Hubo un problema al crear el token de registro" - msgid "The passbolt config is writable." msgstr "Se puede escribir en la configuración de passbolt." @@ -3226,8 +3772,14 @@ msgstr "No se puede escribir en la configuración de passbolt." msgid "Ensure the file " msgstr "Asegúrese de que el archivo " -msgid "you can try:" -msgstr "puedes probar:" +msgid "The server OpenPGP private key file is writable." +msgstr "El archivo de clave privada OpenPGP del servidor tiene permisos de escritura." + +msgid "The server OpenPGP private key file is not writable." +msgstr "El archivo de clave privada OpenPGP del servidor no tiene permisos de escritura." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Asegúrese de que el archivo {0} tiene permisos de escritura para el usuario del servidor web." msgid "The server OpenPGP public key file is writable." msgstr "El archivo de clave pública OpenPGP del servidor tiene permisos de escritura." @@ -3235,14 +3787,17 @@ msgstr "El archivo de clave pública OpenPGP del servidor tiene permisos de escr msgid "The server OpenPGP public key file is not writable." msgstr "El archivo de clave pública OpenPGP del servidor no tiene permisos de escritura." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Asegúrese de que el archivo {0} tiene permisos de escritura para el usuario del servidor web." +msgid "The database schema does not match the one expected" +msgstr "El esquema de base de datos no coincide con el esperado" -msgid "The server OpenPGP private key file is writable." -msgstr "El archivo de clave privada OpenPGP del servidor tiene permisos de escritura." +msgid "The database cannot be installed" +msgstr "No se puede instalar la base de datos" -msgid "The server OpenPGP private key file is not writable." -msgstr "El archivo de clave privada OpenPGP del servidor no tiene permisos de escritura." +msgid "There was a problem creating the first user" +msgstr "Hubo un problema al crear el primer usuario" + +msgid "There was a problem creating the registration token" +msgstr "Hubo un problema al crear el token de registro" msgid "Create your user account!" msgstr "¡Crea tu cuenta de usuario!" @@ -3442,18 +3997,9 @@ msgstr "La reescritura de URL no está correctamente configurada en tu servidor. msgid "GPG is configured correctly." msgstr "GPG está configurado correctamente." -msgid "GPG Configuration" -msgstr "Configuración GPG" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "El acceso SSL está habilitado." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "El acceso SSL no está habilitado. Todavía puede continuar, pero es altamente recomendable que configure su servidor web para que use HTTPS antes de continuar." - msgid "Start configuration" msgstr "Iniciar configuración" @@ -3544,9 +4090,6 @@ msgstr "Comprobaciones de salud" msgid "Passbolt API Status" msgstr "Passbolt API Status" -msgid "SSL access is not enabled." -msgstr "El acceso SSL no está habilitado." - msgid "Group manager" msgstr "Administrador de grupo" diff --git a/resources/locales/fr_FR/default.po b/resources/locales/fr_FR/default.po index 55a0f3b475..31c894881c 100644 --- a/resources/locales/fr_FR/default.po +++ b/resources/locales/fr_FR/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:56\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: French\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Validation du groupe {0} réussie" msgid "Could not validate group user data." msgstr "Impossible de valider les données d'utilisateur de groupe." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "non défini" + +msgid "Could not connect to github repository" +msgstr "Impossible de se connecter au dépôt github" + +msgid "Could not read tag information on github repository" +msgstr "Impossible de lire les informations de tag sur le dépôt github" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "vous pouvez essayer :" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Base de données" + +msgid "GPG Configuration" +msgstr "Configuration GPG" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "L'accès SSL est activé." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "L'accès SSL n'est pas activé. Vous pouvez toujours continuer, mais il est fortement recommandé de configurer votre serveur web pour qu'il utilise HTTPS avant de continuer." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Impossible de valider les données de la sous-clé." @@ -1450,15 +1981,6 @@ msgstr "Validation de l'utilisateur {0} réussie" msgid "The directory {0} cannot be deleted" msgstr "Le dossier {0} ne peut pas être supprimé" -msgid "Database connection failed" -msgstr "La connexion à la base de données a échoué" - -msgid "Could not connect to github repository" -msgstr "Impossible de se connecter au dépôt github" - -msgid "Could not read tag information on github repository" -msgstr "Impossible de lire les informations de tag sur le dépôt github" - msgid "The key {0} cannot be used to encrypt." msgstr "La clé {0} ne peut pas être utilisée pour chiffrer." @@ -1849,6 +2371,21 @@ msgstr "La clé privée JWT doit faire au moins {0} octets." msgid "The configuration {0} is not correctly set." msgstr "La configuration {0} n'est pas correctement définie." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Le jeton de rafraîchissement doit être un UUID valide." @@ -3034,29 +3571,53 @@ msgstr "" msgid "The client should be a valid IP or a valid domain." msgstr "" -msgid "Could not validate the smtp settings." -msgstr "Échec de la validation des paramètres SMTP." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "Échec de la validation des paramètres SMTP stockés dans la base de données." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "La clé OpenPGP du serveur ne permet pas de déchiffrer les paramètres SMTP stockés dans la base de données." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Pour résoudre ce problème, vous devez reconfigurer le serveur SMTP." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "non trouvé" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "base de données" msgid "env variables" msgstr "variables d'environnement" -msgid "undefined" -msgstr "non défini" +msgid "Could not validate the smtp settings." +msgstr "Échec de la validation des paramètres SMTP." + +msgid "Could not validate the smtp settings found in database." +msgstr "Échec de la validation des paramètres SMTP stockés dans la base de données." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "La clé OpenPGP du serveur ne permet pas de déchiffrer les paramètres SMTP stockés dans la base de données." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Pour résoudre ce problème, vous devez reconfigurer le serveur SMTP." msgid "Passbolt test email" msgstr "E-mail de test Passbolt" @@ -3088,9 +3649,6 @@ msgstr "Vérification du système" msgid "Subscription key" msgstr "Clé de souscription" -msgid "Database" -msgstr "Base de données" - msgid "Server keys" msgstr "Clés du serveur" @@ -3205,18 +3763,6 @@ msgstr "Un statut pour forcer SSL est requis." msgid "The force ssl setting should be a valid boolean." msgstr "Le réglage Force ssl doit être un booléen valide." -msgid "The database schema does not match the one expected" -msgstr "Le schéma de base de données ne correspond pas à celui attendu" - -msgid "The database cannot be installed" -msgstr "La base de données ne peut pas être installée" - -msgid "There was a problem creating the first user" -msgstr "Un problème est survenu lors de la création du premier utilisateur" - -msgid "There was a problem creating the registration token" -msgstr "Un problème est survenu lors de la création du jeton d'enregistrement" - msgid "The passbolt config is writable." msgstr "La configuration de passbolt est accessible en écriture." @@ -3226,8 +3772,14 @@ msgstr "La configuration de passbolt n'est pas accessible en écriture." msgid "Ensure the file " msgstr "Assurez-vous que le fichier " -msgid "you can try:" -msgstr "vous pouvez essayer :" +msgid "The server OpenPGP private key file is writable." +msgstr "Le fichier de clé privée OpenPGP du serveur est accessible en écriture." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Le fichier de clé privée OpenPGP du serveur n'est pas accessible en écriture." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Assurez-vous que le fichier {0} est accessible en écriture par l'utilisateur du serveur web." msgid "The server OpenPGP public key file is writable." msgstr "Le fichier de clé publique OpenPGP du serveur est accessible en écriture." @@ -3235,14 +3787,17 @@ msgstr "Le fichier de clé publique OpenPGP du serveur est accessible en écritu msgid "The server OpenPGP public key file is not writable." msgstr "Le fichier de clé publique OpenPGP du serveur n'est pas accessible en écriture." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Assurez-vous que le fichier {0} est accessible en écriture par l'utilisateur du serveur web." +msgid "The database schema does not match the one expected" +msgstr "Le schéma de base de données ne correspond pas à celui attendu" -msgid "The server OpenPGP private key file is writable." -msgstr "Le fichier de clé privée OpenPGP du serveur est accessible en écriture." +msgid "The database cannot be installed" +msgstr "La base de données ne peut pas être installée" -msgid "The server OpenPGP private key file is not writable." -msgstr "Le fichier de clé privée OpenPGP du serveur n'est pas accessible en écriture." +msgid "There was a problem creating the first user" +msgstr "Un problème est survenu lors de la création du premier utilisateur" + +msgid "There was a problem creating the registration token" +msgstr "Un problème est survenu lors de la création du jeton d'enregistrement" msgid "Create your user account!" msgstr "Créez votre compte utilisateur!" @@ -3442,18 +3997,9 @@ msgstr "La réécriture d'URL n'est pas correctement configurée sur votre serve msgid "GPG is configured correctly." msgstr "GPG est configuré correctement." -msgid "GPG Configuration" -msgstr "Configuration GPG" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "L'accès SSL est activé." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "L'accès SSL n'est pas activé. Vous pouvez toujours continuer, mais il est fortement recommandé de configurer votre serveur web pour qu'il utilise HTTPS avant de continuer." - msgid "Start configuration" msgstr "Lancer la configuration" @@ -3544,9 +4090,6 @@ msgstr "Bilan de santé" msgid "Passbolt API Status" msgstr "Passbolt API Status" -msgid "SSL access is not enabled." -msgstr "L'accès SSL n'est pas activé." - msgid "Group manager" msgstr "Responsable du groupe" diff --git a/resources/locales/it_IT/default.po b/resources/locales/it_IT/default.po index ad6fd7fc96..2cf5a45c01 100644 --- a/resources/locales/it_IT/default.po +++ b/resources/locales/it_IT/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:57\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Italian\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Validazione del gruppo {0} riuscita" msgid "Could not validate group user data." msgstr "Impossibile convalidare i dati utente del gruppo." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "" + +msgid "Could not connect to github repository" +msgstr "Impossibile collegarsi al repository GitHub" + +msgid "Could not read tag information on github repository" +msgstr "Impossibile leggere le informazioni dei tag nel repository GitHub" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "puoi provare:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Database" + +msgid "GPG Configuration" +msgstr "Configurazione GPG" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "Accesso SSL abilitato." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "L'accesso SSL non è attivato. È ancora possibile procedere, ma è altamente raccomandato configurare il server web per utilizzare HTTPS prima di continuare." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Impossibile convalidare i dati della sottochiave." @@ -1450,15 +1981,6 @@ msgstr "Validazione dell'utente {0} riuscita" msgid "The directory {0} cannot be deleted" msgstr "La directory {0} non può essere eliminata" -msgid "Database connection failed" -msgstr "Connessione al database non riuscita" - -msgid "Could not connect to github repository" -msgstr "Impossibile collegarsi al repository GitHub" - -msgid "Could not read tag information on github repository" -msgstr "Impossibile leggere le informazioni dei tag nel repository GitHub" - msgid "The key {0} cannot be used to encrypt." msgstr "Impossibile usare la chiave {0} per la cifratura." @@ -1849,6 +2371,21 @@ msgstr "La chiave privata JWT dovrebbe essere lunga almeno {0} byte." msgid "The configuration {0} is not correctly set." msgstr "La configurazione {0} non è impostata correttamente." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Il token di aggiornamento dovrebbe essere un UUID valido." @@ -3034,29 +3571,53 @@ msgstr "Endpoint impostazioni SMTP disabilitati." msgid "The client should be a valid IP or a valid domain." msgstr "Il client deve essere un IP o un dominio valido." -msgid "Could not validate the smtp settings." -msgstr "Non è stato possibile convalidare le impostazioni SMTP." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "Non è stato possibile convalidare le impostazioni SMTP trovate nel database." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "Non è possibile utilizzare la chiave del server OpenPGP per decifrare le impostazioni SMTP memorizzate nel database." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Per risolvere il problema, è necessario ripetere la configurazione del server SMTP." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "non trovato" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "database" msgid "env variables" msgstr "" -msgid "undefined" -msgstr "" +msgid "Could not validate the smtp settings." +msgstr "Non è stato possibile convalidare le impostazioni SMTP." + +msgid "Could not validate the smtp settings found in database." +msgstr "Non è stato possibile convalidare le impostazioni SMTP trovate nel database." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "Non è possibile utilizzare la chiave del server OpenPGP per decifrare le impostazioni SMTP memorizzate nel database." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Per risolvere il problema, è necessario ripetere la configurazione del server SMTP." msgid "Passbolt test email" msgstr "" @@ -3088,9 +3649,6 @@ msgstr "Controllo del sistema" msgid "Subscription key" msgstr "Chiave abbonamento" -msgid "Database" -msgstr "Database" - msgid "Server keys" msgstr "Chiavi del server" @@ -3205,18 +3763,6 @@ msgstr "È richiesto uno stato di forza ssl." msgid "The force ssl setting should be a valid boolean." msgstr "L'impostazione della forza ssl dovrebbe essere un booleano valido." -msgid "The database schema does not match the one expected" -msgstr "Lo schema del database non corrisponde a quello previsto" - -msgid "The database cannot be installed" -msgstr "Il database non può essere installato" - -msgid "There was a problem creating the first user" -msgstr "C'è stato un problema durante la creazione del primo utente" - -msgid "There was a problem creating the registration token" -msgstr "C'è stato un problema durante la creazione del token di registrazione" - msgid "The passbolt config is writable." msgstr "La configurazione di passbolt è scrivibile." @@ -3226,8 +3772,14 @@ msgstr "La configurazione di passbolt non è scrivibile." msgid "Ensure the file " msgstr "Accertarsi che il file " -msgid "you can try:" -msgstr "puoi provare:" +msgid "The server OpenPGP private key file is writable." +msgstr "Il file di chiavi private OpenPGP del server è scrivibile." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Il file di chiavi private OpenPGP del server non è scrivibile." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Assicurati che il file {0} sia scrivibile dall'utente del webserver." msgid "The server OpenPGP public key file is writable." msgstr "Il file di chiave pubblica OpenPGP del server è scrivibile." @@ -3235,14 +3787,17 @@ msgstr "Il file di chiave pubblica OpenPGP del server è scrivibile." msgid "The server OpenPGP public key file is not writable." msgstr "Il file di chiave pubblica OpenPGP del server non è scrivibile." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Assicurati che il file {0} sia scrivibile dall'utente del webserver." +msgid "The database schema does not match the one expected" +msgstr "Lo schema del database non corrisponde a quello previsto" -msgid "The server OpenPGP private key file is writable." -msgstr "Il file di chiavi private OpenPGP del server è scrivibile." +msgid "The database cannot be installed" +msgstr "Il database non può essere installato" -msgid "The server OpenPGP private key file is not writable." -msgstr "Il file di chiavi private OpenPGP del server non è scrivibile." +msgid "There was a problem creating the first user" +msgstr "C'è stato un problema durante la creazione del primo utente" + +msgid "There was a problem creating the registration token" +msgstr "C'è stato un problema durante la creazione del token di registrazione" msgid "Create your user account!" msgstr "Crea il tuo account utente!" @@ -3442,18 +3997,9 @@ msgstr "La riscrittura URL non è stata configurata correttamente nel tuo server msgid "GPG is configured correctly." msgstr "Il GPG è configurato correttamente." -msgid "GPG Configuration" -msgstr "Configurazione GPG" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "Accesso SSL abilitato." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "L'accesso SSL non è attivato. È ancora possibile procedere, ma è altamente raccomandato configurare il server web per utilizzare HTTPS prima di continuare." - msgid "Start configuration" msgstr "Inizia la configurazione" @@ -3544,9 +4090,6 @@ msgstr "Controlli sanitari" msgid "Passbolt API Status" msgstr "Stato API Passbolt" -msgid "SSL access is not enabled." -msgstr "Accesso SSL non abilitato." - msgid "Group manager" msgstr "Gestore gruppo" diff --git a/resources/locales/ja_JP/default.po b/resources/locales/ja_JP/default.po index 9d4a554bef..785323dc54 100644 --- a/resources/locales/ja_JP/default.po +++ b/resources/locales/ja_JP/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:57\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Japanese\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "グループ {0} の検証に成功しました" msgid "Could not validate group user data." msgstr "グループユーザーデータを検証できませんでした。" +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "" + +msgid "Could not connect to github repository" +msgstr "Githubリポジトリに接続できませんでした" + +msgid "Could not read tag information on github repository" +msgstr "Githubリポジトリのタグ情報を読み取ることができませんでした" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "以下を試せます:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "データベース" + +msgid "GPG Configuration" +msgstr "GPG設定" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "SSLアクセスが有効になっています。" + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "SSLアクセスが有効になっていません。続行することはできますが、続行する前にウェブサーバーをHTTPSを使用するように設定することを強くお勧めします。" + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "" @@ -1450,15 +1981,6 @@ msgstr "ユーザー {0} の検証に成功しました" msgid "The directory {0} cannot be deleted" msgstr "" -msgid "Database connection failed" -msgstr "" - -msgid "Could not connect to github repository" -msgstr "Githubリポジトリに接続できませんでした" - -msgid "Could not read tag information on github repository" -msgstr "Githubリポジトリのタグ情報を読み取ることができませんでした" - msgid "The key {0} cannot be used to encrypt." msgstr "鍵 {0} は暗号化に使用できません。" @@ -1849,6 +2371,21 @@ msgstr "JWT 秘密鍵は少なくとも {0} バイト長でなければなりま msgid "The configuration {0} is not correctly set." msgstr "設定 {0} が正しく設定されていません。" +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "リフレッシュトークンは有効なUUIDでなければなりません。" @@ -3034,28 +3571,52 @@ msgstr "" msgid "The client should be a valid IP or a valid domain." msgstr "" -msgid "Could not validate the smtp settings." +msgid "SMTP Settings coherent. You may send a test email to validate them." msgstr "" -msgid "Could not validate the smtp settings found in database." +msgid "SMTP Setting errors: {0}" msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgid "The {0} plugin endpoints are disabled." msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." msgstr "" msgid "not found" msgstr "" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "データベース" msgid "env variables" msgstr "" -msgid "undefined" +msgid "Could not validate the smtp settings." +msgstr "" + +msgid "Could not validate the smtp settings found in database." +msgstr "" + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "" + +msgid "To fix this problem, you need to configure the SMTP server again." msgstr "" msgid "Passbolt test email" @@ -3088,9 +3649,6 @@ msgstr "システムチェック" msgid "Subscription key" msgstr "サブスクリプションキー" -msgid "Database" -msgstr "データベース" - msgid "Server keys" msgstr "サーバーキー" @@ -3205,18 +3763,6 @@ msgstr "強制ssl 状態が必要です。" msgid "The force ssl setting should be a valid boolean." msgstr "強制ssl 設定は有効なブール値である必要があります。" -msgid "The database schema does not match the one expected" -msgstr "データベーススキーマが期待されているものと一致しません" - -msgid "The database cannot be installed" -msgstr "データベースをインストールできません" - -msgid "There was a problem creating the first user" -msgstr "最初のユーザーを作成する際に問題が発生しました" - -msgid "There was a problem creating the registration token" -msgstr "登録トークンの作成中に問題が発生しました" - msgid "The passbolt config is writable." msgstr "パスボルトのconfigは書き込み可能です。" @@ -3226,8 +3772,14 @@ msgstr "パスボルトのconfigは書き込み可能ではありません。" msgid "Ensure the file " msgstr "ファイルを確認 " -msgid "you can try:" -msgstr "以下を試せます:" +msgid "The server OpenPGP private key file is writable." +msgstr "サーバーのOpenPGP秘密鍵ファイルは書き込み可能です。" + +msgid "The server OpenPGP private key file is not writable." +msgstr "サーバーのOpenPGP秘密鍵ファイルは書き込み可能ではありません。" + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "ファイル {0} がウェブサーバーユーザーによって書き込み可能であることを確認します。" msgid "The server OpenPGP public key file is writable." msgstr "サーバーのOpenPGP公開鍵ファイルは書き込み可能です。" @@ -3235,14 +3787,17 @@ msgstr "サーバーのOpenPGP公開鍵ファイルは書き込み可能です msgid "The server OpenPGP public key file is not writable." msgstr "サーバーのOpenPGP公開鍵ファイルは書き込みできません。" -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "ファイル {0} がウェブサーバーユーザーによって書き込み可能であることを確認します。" +msgid "The database schema does not match the one expected" +msgstr "データベーススキーマが期待されているものと一致しません" -msgid "The server OpenPGP private key file is writable." -msgstr "サーバーのOpenPGP秘密鍵ファイルは書き込み可能です。" +msgid "The database cannot be installed" +msgstr "データベースをインストールできません" -msgid "The server OpenPGP private key file is not writable." -msgstr "サーバーのOpenPGP秘密鍵ファイルは書き込み可能ではありません。" +msgid "There was a problem creating the first user" +msgstr "最初のユーザーを作成する際に問題が発生しました" + +msgid "There was a problem creating the registration token" +msgstr "登録トークンの作成中に問題が発生しました" msgid "Create your user account!" msgstr "ユーザーアカウントを作成してください!" @@ -3442,18 +3997,9 @@ msgstr "URLの書き換えがサーバーで正しく設定されていません msgid "GPG is configured correctly." msgstr "GPGは正しく設定されています。" -msgid "GPG Configuration" -msgstr "GPG設定" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "SSLアクセスが有効になっています。" - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "SSLアクセスが有効になっていません。続行することはできますが、続行する前にウェブサーバーをHTTPSを使用するように設定することを強くお勧めします。" - msgid "Start configuration" msgstr "設定を開始" @@ -3544,9 +4090,6 @@ msgstr "ヘルスチェック" msgid "Passbolt API Status" msgstr "パスボルトAPIステータス" -msgid "SSL access is not enabled." -msgstr "SSLアクセスが有効になっていません。" - msgid "Group manager" msgstr "グループマネージャー" diff --git a/resources/locales/ko_KR/default.po b/resources/locales/ko_KR/default.po index dabe058214..5766cae345 100644 --- a/resources/locales/ko_KR/default.po +++ b/resources/locales/ko_KR/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:56\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-27 07:12\n" "Last-Translator: NAME \n" "Language-Team: Korean\n" "MIME-Version: 1.0\n" @@ -755,7 +755,7 @@ msgid "The identifier of the access request object should not be empty." msgstr "접근 요청 개체 식별자는 비워 둘 수 없습니다." msgid "A permission already exists for the given access control object and access request object." -msgstr "지정된 접근 제어 개체 및 액세스 요청 개체에 대한 사용 권한이 이미 있습니다." +msgstr "지정된 접근 제어 개체 및 접근 요청 개체에 대한 사용 권한이 이미 있습니다." msgid "The access control object does not exist." msgstr "접근 제어 개체가 없습니다." @@ -1240,6 +1240,537 @@ msgstr "{0} 그룹에 대한 유효성 검증 성공" msgid "Could not validate group user data." msgstr "그룹 사용자 데이터를 검사할 수 없습니다." +msgid "All email notifications will be sent." +msgstr "모든 이메일 알림이 전송됩니다." + +msgid "Some email notifications are disabled by the administrator." +msgstr "관리자가 일부 이메일 알림을 비활성화했습니다." + +msgid "Host availability will be checked." +msgstr "호스트 가용성이 확인됩니다." + +msgid "Host availability checking is disabled." +msgstr "호스트 가용성 확인이 비활성화되었습니다." + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "이 인스턴스가 인터넷에서 공개적으로 사용 가능하지 않은지 확인하세요." + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "또는 PASSBOLT_EMAIL_VALIDATE_MX 환경 변수를 true로 설정합니다." + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "또는 {0}에서 passbolt.email.validate.mx 을 true로 설정합니다." + +msgid "Serving the compiled version of the javascript app." +msgstr "자바스크립트 앱의 컴파일된 버전을 제공합니다." + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "컴파일되지 않은 자바스크립트를 사용하면 패스볼트 속도가 느려집니다." + +msgid "Set passbolt.js.build to production in {0}" +msgstr "{0}에서 passbolt.js.build를 프로덕션으로 설정" + +msgid "undefined" +msgstr "미정" + +msgid "Could not connect to github repository" +msgstr "github 리포지토리에 연결할 수 없습니다." + +msgid "Could not read tag information on github repository" +msgstr "github 리포지토리에 태그 정보를 읽을 수 없습니다." + +msgid "Using latest passbolt version ({0})." +msgstr "최신 패스볼트 버전({0})을 사용." + +msgid "Could connect to passbolt repository to check versions." +msgstr "버전을 확인하기 위해 패스볼트 저장소에 연결할 수 있습니다." + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "이 설치는 최신 상태가 아닙니다. 현재 {0}을(를) 사용하고 있으며 {1}이어야 합니다." + +msgid "Could not connect to passbolt repository to check versions" +msgstr "버전을 확인하기 위해 패스볼트 저장소에 연결할 수 없습니다" + +msgid "It is not possible check if your version is up to date." +msgstr "버전이 최신인지 확인할 수 없습니다." + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "https://www.passbolt.com/help/tech/update 를 참조하세요." + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "이 스크립트가 업데이트를 확인할 수 있도록 네트워크 구성을 확인하세요." + +msgid "Search engine robots are told not to index content." +msgstr "검색 엔진 로봇들은 콘텐츠를 인덱싱하지 말라고 지시됩니다." + +msgid "Search engine robots are not told not to index content." +msgstr "검색 엔진 로봇들에게 콘텐츠를 인덱싱하지 말라고 지시되지 않습니다." + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "{0}에서 passbolt.meta.roots를 false로 설정합니다." + +msgid "Selenium API endpoints are disabled." +msgstr "Selenium API 엔드포인트가 비활성화되었습니다." + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "Selenium API 엔드포인트가 활성화되어 있습니다. 이 설정은 테스트 용도로만 사용해야 합니다." + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "{0}에서 passbolt.selenium.active를 false로 설정합니다." + +msgid "The Self Registration plugin is enabled." +msgstr "자체 등록 플러그인이 활성화되었습니다." + +msgid "The Self Registration plugin is disabled." +msgstr "자체 등록 플러그인이 비활성화되었습니다." + +msgid "Enable the plugin in order to define self registration settings." +msgstr "자체 등록 설정을 정의하려면 플러그인을 사용합니다." + +msgid "Registration is closed, only administrators can add users." +msgstr "가입이 종료되었습니다. 사용자를 추가할 수 있는 권한은 관리자에게만 있습니다." + +msgid "The self registration provider is: {0}." +msgstr "자체 등록 제공자 : {0}." + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "더 이상 사용되지 않는 자체 등록 공개 설정을 {0} 에서 찾을 수 없습니다." + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "더 이상 사용되지 않는 자체 등록 공개 설정이 {0} 에서 발견되었습니다." + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "\"passbolt.registration.public\" 설정을 제거할 수 있습니다." + +msgid "Passbolt is configured to force SSL use." +msgstr "패스볼트가 SSL을 강제로 사용하도록 구성되어 있습니다." + +msgid "Passbolt is not configured to force SSL use." +msgstr "패스볼트가 SSL을 강제로 사용하도록 구성되지 않았습니다." + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "{0}에서 passbolt.ssl.force를 true로 설정합니다." + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "App.fullBaseUrl이 HTTPS로 설정되었습니다." + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "App.fullBaseUrl이 HTTPS로 설정되지 않았습니다." + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "{0}에서 App.fullBaseUrl url 스킴을 확인하세요." + +msgid "The application config file is present" +msgstr "애플리케이션 구성 파일이 존재합니다." + +msgid "The application config file is missing in {0}" +msgstr "{0} 에 애플리케이션 구성 파일이 없습니다." + +msgid "Copy {0} to {1}" +msgstr "{0} 을(를) {1} 에 복사" + +msgid "The passbolt config file is present" +msgstr "패스볼트 구성 파일이 존재합니다." + +msgid "The passbolt config file is missing in {0}" +msgstr "{0} 에 패스볼트 구성 파일이 없습니다." + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "패스볼트가 환경 변수로 구성된 경우 패스볼트 구성 파일이 필요하지 않습니다." + +msgid "Cache is working." +msgstr "캐시가 작동 중입니다." + +msgid "Cache is NOT working." +msgstr "캐시가 작동 중이지 않습니다." + +msgid "Check the settings in {0}" +msgstr "{0} 의 설정을 확인하세요." + +msgid "Debug mode is off." +msgstr "디버그 모드가 꺼져 있습니다." + +msgid "Debug mode is on." +msgstr "디버그 모드가 켜져 있습니다." + +msgid "Set debug to false in {0}" +msgstr "{0} 에서 디버그를 false로 설정" + +msgid "Full base url is set to {0}" +msgstr "전체 기본 url이 {0} (으)로 설정됨" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "전체 기본 url이 설정되지 않았습니다. 애플리케이션이 {0} 을(를) 사용하고 있습니다." + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "{0}에서 App.fullBaseUrl을 편집하세요." + +msgid "/healthcheck/status is reachable." +msgstr "/healthcheck/status에 접근할 수 있습니다." + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "App.fullBaseUrl에 지정된 URL로 /healthcheck/status에 도달할 수 없습니다." + +msgid "Check that the domain name is correct in {0}" +msgstr "{0} 의 도메인 이름이 올바른지 확인하세요." + +msgid "Check the network settings" +msgstr "네트워크 설정을 확인하세요" + +msgid "Unique value set for security.salt" +msgstr "security.salt에 대해 고유한 값이 설정되었습니다." + +msgid "Default value found for security.salt" +msgstr "security.salt에 대한 기본값이 발견되었습니다." + +msgid "Edit the security.salt in {0}" +msgstr "{0}에서 security.salt를 편집하세요." + +msgid "App.fullBaseUrl validation OK." +msgstr "App.fullBaseUrl 유효성 검사가 완료되었습니다." + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "App.fullBaseUrl이 유효성을 검사하지 않습니다. {0}." + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "http://www.ietf.org/rfc/rfc1035.txt의 섹션 2.3.1에 정의된 대로 유효한 도메인 이름을 선택하세요." + +msgid "The application is able to connect to the database" +msgstr "애플리케이션이 데이터베이스에 연결할 수 있습니다." + +msgid "The driver defined in the database configuration is not supported." +msgstr "데이터베이스 구성에 정의된 드라이버가 지원되지 않습니다." + +msgid "The application is not able to connect to the database." +msgstr "애플리케이션이 데이터베이스에 연결할 수 없습니다." + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "{0} 에 정의된 드라이버가 다음 중 하나인지 확인하세요: {1}." + +msgid "Double check the host, database name, username and password in {0}." +msgstr "{0} 에서 호스트, 데이터베이스 이름, 사용자 이름 및 비밀번호를 다시 확인하세요." + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "데이터베이스가 존재하고 지정된 데이터베이스 사용자가 접근할 수 있는지 확인하십시오." + +msgid "Some default content is present." +msgstr "일부 기본 콘텐츠가 있습니다." + +msgid "No default content found." +msgstr "기본 콘텐츠를 찾을 수 없습니다." + +msgid "Run the install script to install the database tables" +msgstr "설치 스크립트를 실행하여 데이터베이스 테이블을 설치하세요" + +msgid "The database schema up to date." +msgstr "데이터베이스 스키마가 최신 상태입니다." + +msgid "The database schema is not up to date." +msgstr "데이터베이스 스키마가 최신 상태가 아닙니다." + +msgid "Run the migration scripts:" +msgstr "마이그레이션 스크립트를 실행하세요:" + +msgid "{0} tables found." +msgstr "{0} 테이블이 발견됨." + +msgid "No table found." +msgstr "테이블을 찾을 수 없습니다." + +msgid "GD or Imagick extension is installed." +msgstr "GD 또는 Imagick 확장 프로그램이 설치되어 있습니다." + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "패스볼트를 사용하려면 gd 또는 imagick 확장을 활성화해야 합니다." + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "https://secure.php.net/manual/en/book.image.php 를 참조하세요." + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "https://secure.php.net/manual/en/book.imagick.php 를 참조하세요." + +msgid "Intl extension is installed." +msgstr "intl 확장이 설치되었습니다." + +msgid "You must enable the intl extension to use Passbolt." +msgstr "패스볼트를 사용하려면 intl 확장을 활성화해야 합니다." + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "https://secure.php.net/manual/en/book.intl.php 를 참조하세요." + +msgid "The logs directory and its content are writable." +msgstr "로그 디렉터리와 해당 콘텐츠는 쓰기 가능합니다." + +msgid "The logs directory and its content are not writable." +msgstr "로그 디렉터리와 해당 콘텐츠는 쓰기 가능지 않습니다." + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "웹 서버 사용자가 로그 디렉터리와 해당 내용을 쓸 수 있는지 확인하세요." + +msgid "you can try:" +msgstr "시도해볼 것:" + +msgid "Mbstring extension is installed." +msgstr "mbstring 확장이 설치되었습니다." + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "패스볼트를 사용하려면 mbstring 확장을 활성화해야 합니다." + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "https://secure.php.net/manual/en/book.mbstring.php 를 참조하세요." + +msgid "PHP version is {0} or above." +msgstr "PHP 버전은 {0} 이상입니다." + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "{0} 미만의 PHP 버전은 곧 패스볼트에서 지원되지 않으므로 운영 체제나 PHP 환경을 업그레이드하는 것이 좋습니다." + +msgid "PCRE compiled with unicode support." +msgstr "유니코드 지원으로 컴파일된 PCRE." + +msgid "PCRE has not been compiled with Unicode support." +msgstr "PCRE는 유니코드 지원으로 컴파일되지 않았습니다." + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "구성 시 --enable-unicode-properties 를 추가하여 유니코드 지원으로 PCRE를 다시 컴파일하십시오." + +msgid "PHP version {0}." +msgstr "PHP 버전 {0}." + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "PHP 버전이 너무 낮습니다. 패스볼트는 PHP {0} 이상이 필요합니다." + +msgid "The temporary directory and its content are writable and not executable." +msgstr "임시 디렉터리와 해당 콘텐츠는 쓰기 가능하지만 실행 가능하지 않습니다." + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "임시 디렉터리와 해당 콘텐츠는 쓸 수 없거나 실행 가능합니다." + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "웹 서버 사용자가 임시 디렉토리와 해당 컨텐츠를 쓸 수 있는지 확인하십시오." + +msgid "The private key can be used to decrypt a message." +msgstr "개인 키를 사용하여 메시지를 해독할 수 있습니다." + +msgid "The private key cannot be used to decrypt a message" +msgstr "개인 키는 메시지를 해독하는 데 사용할 수 없습니다." + +msgid "The private key can be used to decrypt and verify a message." +msgstr "개인 키는 메시지를 해독하고 확인하는 데 사용될 수 있습니다." + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "개인 키는 메시지를 해독하고 확인하는 데 사용할 수 없습니다." + +msgid "The public key can be used to encrypt a message." +msgstr "공개 키를 사용하여 메시지를 해독할 수 있습니다." + +msgid "The public key cannot be used to encrypt a message" +msgstr "공개 키는 메시지를 해독하는 데 사용할 수 없습니다." + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "서버 개인 키가 유효한지, 암호가 없는지 확인하세요." + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "웹 서버 사용자의 키링에 있는 개인 서버 키를 가져왔는지 확인하세요." + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "공개 키와 개인 키를 사용하여 메시지를 암호화하고 서명할 수 있습니다." + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "공개 키와 개인 키는 메시지를 암호화하고 서명하는 데 사용할 수 없습니다." + +msgid "The private key can be used to sign a message." +msgstr "개인 키를 사용하여 메시지에 서명할 수 있습니다." + +msgid "The private key cannot be used to sign a message" +msgstr "개인 키를 사용하여 메시지에 서명할 수 없습니다." + +msgid "The public key can be used to verify a signature." +msgstr "공개 키를 사용하여 서명을 확인할 수 있습니다." + +msgid "The public key cannot be used to verify a signature." +msgstr "공개 키는 서명을 확인하는 데 사용할 수 없습니다." + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "서버 키 지문이 {0} 에 정의된 지문과 일치합니다." + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "서버 키 지문이 {0} 에 정의된 지문과 일치하지 않습니다." + +msgid "Double check the key fingerprint, example: " +msgstr "키 지문을 다시 확인하세요. 예: " + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "SERVER_KEY_EMAIL: 서버 키를 생성할 때 사용한 이메일입니다." + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "https://www.passbolt.com/help/tech/install#toc_gpg 를 참고하세요." + +msgid "The server private key format is Gopengpg compatible." +msgstr "서버 개인 키 형식은 Gopengpg와 호환됩니다." + +msgid "The server private key format is not Gopengpg compatible." +msgstr "서버 개인 키 형식은 Gopengpg와 호환되지 않습니다." + +msgid "The server public key format is Gopengpg compatible." +msgstr "서버 공개 키 형식은 Gopengpg와 호환됩니다." + +msgid "The server public key format is not Gopengpg compatible." +msgstr "서버 공개 키 형식은 Gopengpg와 호환되지 않습니다." + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "환경 변수 GNUPGOME이 {0} (으)로 설정되었습니다." + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "환경 변수 GNUPGHOME이 {0} 으로 설정되었지만 디렉터리가 존재하지 않습니다." + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "키링 위치가 존재하고 웹 서버 사용자가 접근할 수 있는지 확인하세요." + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "{0} 에서 GPG.env.setenv 및 GPG.env.home 변수를 편집하여 키링 위치를 변경할 수 있습니다." + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "키링이 포함된 {0} 디렉터리는 웹 서버 사용자가 쓸 수 있습니다." + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "키링이 포함된 {0} 디렉터리는 웹 서버 사용자가 쓸 수 없습니다." + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "웹 서버 사용자가 키링 위치에 접근할 수 있는지 확인하세요." + +msgid "The server OpenPGP key is not the default one." +msgstr "서버 OpenPGP 키는 기본 키가 아닙니다." + +msgid "Do not use the default OpenPGP key for the server." +msgstr "서버에 기본 OpenPGP 키를 사용하지 마십시오." + +msgid "The server OpenPGP key is not set." +msgstr "서버 OpenPGP 키가 설정되지 않았습니다." + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "키를 생성 및 내보내기를 하고 {0} 에 지문을 추가하세요." + +msgid "PHP GPG Module is installed and loaded." +msgstr "PHP GPG 모듈이 설치되고 로드됩니다." + +msgid "PHP GPG Module is not installed or loaded." +msgstr "PHP GPG 모듈이 설치되지 않았거나 로드되지 않았습니다." + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "php-gnupg를 설치하세요. http://php.net/manual/en/gnupg.installation.php 를 참고하세요." + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "php-cli와 php 모두에 대해 php ini 파일에 Extension=gnupg.so를 추가해야 합니다." + +msgid "The private key file is defined in {0} and readable." +msgstr "개인 키 파일은 {0} 에 정의되어 있으며 읽을 수 있습니다." + +msgid "The private key file is not defined in {0} or not readable." +msgstr "개인 키 파일이 {0} 에 정의되지 않았거나 읽을 수 없습니다." + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "개인 키 파일이 {0} 의 passbolt.gpg.serverKey.private 변수로 정의되었는지 확인하세요." + +msgid "Ensure there is a private key armored block in the key file." +msgstr "키 파일에 개인 키 강화 블록이 있는지 확인하세요." + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "{0} 에 정의된 개인 키가 있고 웹 서버 사용자가 접근할 수 있는지 확인합니다." + +msgid "There is a valid email id defined for the server key." +msgstr "서버 키에 대해 정의된 유효한 이메일 id가 있습니다." + +msgid "The server key does not have a valid email id." +msgstr "서버 키에 유효한 이메일 id가 없습니다." + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "{0} (또는 환경 변수)에 정의된 서버 공개 키가 키링에 있습니다." + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "{0} (또는 환경 변수)에 정의된 서버 공개 키가 키링에 없습니다." + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "웹 서버 사용자의 키링에 있는 개인 서버 키를 가져옵니다." + +msgid "The public key file is defined in {0} and readable." +msgstr "공개 키 파일은 {0} 에 정의되어 있으며 읽을 수 있습니다." + +msgid "The public key file is not defined in {0} or not readable." +msgstr "공개 키 파일이 {0} 에 정의되지 않았거나 읽을 수 없습니다." + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "공개 키 파일이 {0} 의 passbolt.gpg.serverKey.public 변수로 정의되었는지 확인하세요." + +msgid "Ensure there is a public key armored block in the key file." +msgstr "키 파일에 공개 키 강화 블록이 있는지 확인하세요." + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "{0} 에 정의된 공개 키가 있고 웹 서버 사용자가 접근할 수 있는지 확인합니다." + +msgid "Environment" +msgstr "환경" + +msgid "Config files" +msgstr "구성 파일" + +msgid "Core config" +msgstr "코어 구성" + +msgid "SMTP settings" +msgstr "SMTP 설정" + +msgid "Application configuration" +msgstr "어플리케이션 구성" + +msgid "Database" +msgstr "데이타베이스" + +msgid "GPG Configuration" +msgstr "GPG 구성" + +msgid "JWT Authentication" +msgstr "JWT 인증" + +msgid "SSL Certificate" +msgstr "SSL 인증서" + +msgid "The {0} plugin is enabled." +msgstr "{0} 플러그인이 활성화되었습니다." + +msgid "The {0} plugin is disabled." +msgstr "{0} 플러그인이 비활성화되었습니다." + +msgid "Set the environment variable {0} to true" +msgstr "환경 변수 {0} 을(를) true로 설정하세요." + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "데이터베이스에서 SMTP 설정을 정의하려면 플러그인을 활성화하세요." + +msgid "Hostname is matching in SSL certificate." +msgstr "호스트이름이 SSL 인증서와 일치합니다." + +msgid "Hostname does not match when validating certificates." +msgstr "인증서 유효성을 검사할 때 호스트이름이 일치하지 않습니다." + +msgid "SSL access is enabled." +msgstr "SSL 접근이 활성화되었습니다." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "SSL 접근을 사용할 수 없습니다. 계속 진행할 수 있지만 계속하기 전에 HTTPS를 사용하도록 웹 서버를 구성하는 것이 좋습니다." + +msgid "Not using a self-signed certificate." +msgstr "자체 서명된 인증서를 사용하지 않습니다." + +msgid "Using a self-signed certificate." +msgstr "자체 서명된 인증서를 사용합니다." + +msgid "SSL peer certificate validates." +msgstr "SSL 피어 인증서가 검증됩니다." + +msgid "SSL peer certificate does not validate." +msgstr "SSL 피어 인증서가 검증되지 않습니다." + msgid "Could not validate sub key data." msgstr "하위 키 데이터를 검사할 수 없습니다." @@ -1450,15 +1981,6 @@ msgstr "{0} 사용자에 대한 유효성 검증 성공" msgid "The directory {0} cannot be deleted" msgstr "{0} 디렉토리를 삭제할 수 없습니다" -msgid "Database connection failed" -msgstr "데이터베이스 연결이 실패됨" - -msgid "Could not connect to github repository" -msgstr "github 리포지토리에 연결할 수 없습니다." - -msgid "Could not read tag information on github repository" -msgstr "github 리포지토리에 태그 정보를 읽을 수 없습니다." - msgid "The key {0} cannot be used to encrypt." msgstr "키 {0} 가 암호화에 사용할 수 없습니다." @@ -1849,6 +2371,21 @@ msgstr "JWT 개인키는 {0} 바이트 이상이어야 합니다." msgid "The configuration {0} is not correctly set." msgstr "구성 {0} 이(가) 올바르게 설정되지 않았습니다." +msgid "The {0} directory is not writable." +msgstr "{0} 디렉토리는 쓸 수 없습니다." + +msgid "The {0} directory should not be writable." +msgstr "{0} 디렉토리는 쓰기 가능하지 않아야 합니다." + +msgid "A valid JWT key pair was found." +msgstr "유효한 JWT 키 쌍을 찾았습니다." + +msgid "A valid JWT key pair is missing." +msgstr "유효한 JWT 키 쌍이 없습니다." + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "JWT 키 만들기 스크립트를 실행하여 유효한 JWT 비밀 키와 공개 키 쌍을 만듭니다." + msgid "The refresh token should be a valid UUID." msgstr "리프레쉬 토큰은 유효한 UUID여야 합니다." @@ -2771,7 +3308,7 @@ msgid "The control function should not be empty." msgstr "제어 기능은 비워둘 수 없습니다." msgid "The identifier of the user who created the Rbac should be a valid UUID." -msgstr "역할 기반 액세스 제어를 생성한 사용자의 식별자는 유효한 UUID여야 합니다." +msgstr "역할 기반 접근 제어를 생성한 사용자의 식별자는 유효한 UUID여야 합니다." msgid "The identifier of the user who modified the Rbac should be a valid UUID." msgstr "역할 기반 접근 제어를 수정한 사용자의 식별자는 유효한 UUID여야 합니다." @@ -3034,29 +3571,53 @@ msgstr "SMTP 설정 엔드포인트를 사용할 수 없습니다." msgid "The client should be a valid IP or a valid domain." msgstr "클라이언트는 올바른 IP 또는 도메인이어야 합니다." -msgid "Could not validate the smtp settings." -msgstr "Smtp 설정의 유효성을 검사할 수 없습니다." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "SMTP 설정이 일관됩니다. 이를 확인하기 위해 테스트 이메일을 보낼 수 있습니다." -msgid "Could not validate the smtp settings found in database." -msgstr "데이터베이스에 있는 smtp 설정의 유효성을 검사할 수 없습니다." +msgid "SMTP Setting errors: {0}" +msgstr "SMTP 설정 오류: {0}" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "OpenPGP 서버 키를 사용하여 데이터베이스에 저장된 SMTP 설정을 복호화 할 수 없습니다." +msgid "The {0} plugin endpoints are disabled." +msgstr "{0} 플러그인 엔드포인트가 비활성화되었습니다." -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "이 문제를 해결하려면 SMTP 서버를 다시 구성해야 합니다." +msgid "The {0} plugin endpoints are enabled." +msgstr "{0} 플러그인 엔드포인트가 활성화되었습니다." + +msgid "It is recommended to disable the plugin endpoints." +msgstr "플러그인 엔드포인트를 비활성화하는 것이 좋습니다." + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED 환경 변수를 true로 설정합니다." + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "또는 {0} 에서 passbolt.security.smtpSettings.endpointsDisabled를 true로 설정하세요." msgid "not found" msgstr "찾을 수 없음" +msgid "The SMTP Settings source is: {0}." +msgstr "SMTP 설정 소스는 {0} 입니다." + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "관리 섹션을 통해 데이터베이스에서 SMTP 설정을 지정하는 것이 좋습니다." + msgid "database" msgstr "데이타베이스" msgid "env variables" msgstr "환경 변수" -msgid "undefined" -msgstr "미정" +msgid "Could not validate the smtp settings." +msgstr "Smtp 설정의 유효성을 검사할 수 없습니다." + +msgid "Could not validate the smtp settings found in database." +msgstr "데이터베이스에 있는 smtp 설정의 유효성을 검사할 수 없습니다." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "OpenPGP 서버 키를 사용하여 데이터베이스에 저장된 SMTP 설정을 복호화 할 수 없습니다." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "이 문제를 해결하려면 SMTP 서버를 다시 구성해야 합니다." msgid "Passbolt test email" msgstr "패스볼트 테스트 이메일" @@ -3088,9 +3649,6 @@ msgstr "시스템 체크" msgid "Subscription key" msgstr "구독 키" -msgid "Database" -msgstr "데이타베이스" - msgid "Server keys" msgstr "서버 키" @@ -3205,18 +3763,6 @@ msgstr "강제 ssl 상태가 필요합니다." msgid "The force ssl setting should be a valid boolean." msgstr "강제 ssl 설정은 유효한 부울이어야 합니다." -msgid "The database schema does not match the one expected" -msgstr "데이터베이스 스키마가 예상된 것과 일치하지 않습니다." - -msgid "The database cannot be installed" -msgstr "데이터베이스를 설치할 수 없습니다." - -msgid "There was a problem creating the first user" -msgstr "첫 번째 사용자를 만드는 동안 문제가 발생했습니다." - -msgid "There was a problem creating the registration token" -msgstr "등록 토큰을 만드는 동안 문제가 발생했습니다." - msgid "The passbolt config is writable." msgstr "패스볼트 구성에 쓸 수 있습니다." @@ -3226,8 +3772,14 @@ msgstr "패스볼트 구성에 쓸 수 없습니다." msgid "Ensure the file " msgstr "파일 확인 " -msgid "you can try:" -msgstr "시도해볼 것:" +msgid "The server OpenPGP private key file is writable." +msgstr "서버 OpenPGP 개인키 파일에 쓸 수 있습니다." + +msgid "The server OpenPGP private key file is not writable." +msgstr "서버 OpenPGP 개인키 파일에 쓸 수 없습니다." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "웹 서버 사용자가 {0} 파일을 쓸 수 있는지 확인하세요." msgid "The server OpenPGP public key file is writable." msgstr "서버 OpenPGP 공개키 파일에 쓸 수 있습니다." @@ -3235,14 +3787,17 @@ msgstr "서버 OpenPGP 공개키 파일에 쓸 수 있습니다." msgid "The server OpenPGP public key file is not writable." msgstr "서버 OpenPGP 공개키 파일에 쓸 수 없습니다." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "웹 서버 사용자가 {0} 파일을 쓸 수 있는지 확인하세요." +msgid "The database schema does not match the one expected" +msgstr "데이터베이스 스키마가 예상된 것과 일치하지 않습니다." -msgid "The server OpenPGP private key file is writable." -msgstr "서버 OpenPGP 개인키 파일에 쓸 수 있습니다." +msgid "The database cannot be installed" +msgstr "데이터베이스를 설치할 수 없습니다." -msgid "The server OpenPGP private key file is not writable." -msgstr "서버 OpenPGP 개인키 파일에 쓸 수 없습니다." +msgid "There was a problem creating the first user" +msgstr "첫 번째 사용자를 만드는 동안 문제가 발생했습니다." + +msgid "There was a problem creating the registration token" +msgstr "등록 토큰을 만드는 동안 문제가 발생했습니다." msgid "Create your user account!" msgstr "사용자 계정을 생성!" @@ -3442,18 +3997,9 @@ msgstr "서버에 URL 다시 쓰기가 제대로 구성되지 않았습니다." msgid "GPG is configured correctly." msgstr "GPG가 올바르게 구성되었습니다." -msgid "GPG Configuration" -msgstr "GPG 구성" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "SSL 접근이 활성화되었습니다." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "SSL 접근을 사용할 수 없습니다. 계속 진행할 수 있지만 계속하기 전에 HTTPS를 사용하도록 웹 서버를 구성하는 것이 좋습니다." - msgid "Start configuration" msgstr "구성 시작" @@ -3544,9 +4090,6 @@ msgstr "상태 확인" msgid "Passbolt API Status" msgstr "패스볼트 API 상태" -msgid "SSL access is not enabled." -msgstr "SSL 접근을 사용할 수 없습니다." - msgid "Group manager" msgstr "그룹 관리자" diff --git a/resources/locales/lt_LT/default.po b/resources/locales/lt_LT/default.po index 7d2d81e39d..b405477d7f 100644 --- a/resources/locales/lt_LT/default.po +++ b/resources/locales/lt_LT/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:57\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Lithuanian\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Sėkmingas grupės {0} patvirtinimas" msgid "Could not validate group user data." msgstr "Nepavyko patvirtinti grupės naudotojo duomenų." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "neapibrėžtas" + +msgid "Could not connect to github repository" +msgstr "Nepavyko prisijungti prie „github“ saugyklos" + +msgid "Could not read tag information on github repository" +msgstr "Nepavyko nuskaityti žymos informacijos github.com saugykloje" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "galite pabandyti:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Duomenų bazė" + +msgid "GPG Configuration" +msgstr "GPG konfigūracija" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "SSL prieiga įjungta." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "SSL prieiga neįjungta. Vis tiek galite tęsti, bet labai rekomenduojama prieš tęsiant sukonfigūruoti žiniatinklio serverį naudoti HTTPS." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Nepavyko patvirtinti papildomo rakto duomenų." @@ -1450,15 +1981,6 @@ msgstr "Sėkmingas naudotojo {0} patvirtinimas" msgid "The directory {0} cannot be deleted" msgstr "Katalogas {0} negali buti ištrintas" -msgid "Database connection failed" -msgstr "Nepavyko prisijungti prie duomenų bazės\n" - -msgid "Could not connect to github repository" -msgstr "Nepavyko prisijungti prie „github“ saugyklos" - -msgid "Could not read tag information on github repository" -msgstr "Nepavyko nuskaityti žymos informacijos github.com saugykloje" - msgid "The key {0} cannot be used to encrypt." msgstr "Raktas {0} negali būti naudojamas šifruoti." @@ -1849,6 +2371,21 @@ msgstr "JWT privatusis raktas turi būti bent {0} baitų ilgio." msgid "The configuration {0} is not correctly set." msgstr "Konfigūracija {0} neteisingai nustatyta." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Atnaujinimo prieigos raktas turi būti galiojantis UUID." @@ -3034,29 +3571,53 @@ msgstr "SMTP nustatymų galiniai taškai išjungti.\n" msgid "The client should be a valid IP or a valid domain." msgstr "Klientas turi būti galiojantis IP arba galiojantis domenas." -msgid "Could not validate the smtp settings." -msgstr "Nepavyko patvirtinti smtp nustatymų." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "Nepavyko patvirtinti duomenų bazėje rastų smtp nustatymų." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "OpenPGP serverio raktas negali būti naudojamas duomenų bazėje saugomiems SMTP parametrams iššifruoti." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Norėdami išspręsti šią problemą, turite dar kartą sukonfigūruoti SMTP serverį." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "nerasta" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "duomenų bazė" msgid "env variables" msgstr "env kintamieji" -msgid "undefined" -msgstr "neapibrėžtas" +msgid "Could not validate the smtp settings." +msgstr "Nepavyko patvirtinti smtp nustatymų." + +msgid "Could not validate the smtp settings found in database." +msgstr "Nepavyko patvirtinti duomenų bazėje rastų smtp nustatymų." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "OpenPGP serverio raktas negali būti naudojamas duomenų bazėje saugomiems SMTP parametrams iššifruoti." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Norėdami išspręsti šią problemą, turite dar kartą sukonfigūruoti SMTP serverį." msgid "Passbolt test email" msgstr "Passbol bandomasis el. paštas" @@ -3088,9 +3649,6 @@ msgstr "Sistemos patikrinimas" msgid "Subscription key" msgstr "Prenumeratos raktas." -msgid "Database" -msgstr "Duomenų bazė" - msgid "Server keys" msgstr "Serverio raktai" @@ -3205,18 +3763,6 @@ msgstr "Reikalinga priverstinė ssl būsena." msgid "The force ssl setting should be a valid boolean." msgstr "Priverstinis ssl nustatymas turi būti tinkamas loginis dydis." -msgid "The database schema does not match the one expected" -msgstr "Duomenų bazės schema neatitinka tos, kurios laukiama" - -msgid "The database cannot be installed" -msgstr "Duomenų bazės įdiegti negalima" - -msgid "There was a problem creating the first user" -msgstr "Kuriant pirmąjį naudotoją kilo problema" - -msgid "There was a problem creating the registration token" -msgstr "Kuriant registracijos prieigos raktą kilo problema" - msgid "The passbolt config is writable." msgstr "„Pasbolt“ konfigūracija yra įrašoma." @@ -3226,8 +3772,14 @@ msgstr "„Pasbolt“ konfigūracija nėra įrašoma." msgid "Ensure the file " msgstr "Užtikrinti failą" -msgid "you can try:" -msgstr "galite pabandyti:" +msgid "The server OpenPGP private key file is writable." +msgstr "Serverio OpenPGP privataus rakto failas yra rašomas." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Serverio OpenPGP privataus rakto failas neįrašomas." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Įsitikinkite, kad failą {0} gali įrašyti žiniatinklio serverio naudotojas." msgid "The server OpenPGP public key file is writable." msgstr "Serverio OpenPGP viešojo rakto failas yra rašomas." @@ -3235,14 +3787,17 @@ msgstr "Serverio OpenPGP viešojo rakto failas yra rašomas." msgid "The server OpenPGP public key file is not writable." msgstr "Serverio OpenPGP viešojo rakto failas neįrašomas." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Įsitikinkite, kad failą {0} gali įrašyti žiniatinklio serverio naudotojas." +msgid "The database schema does not match the one expected" +msgstr "Duomenų bazės schema neatitinka tos, kurios laukiama" -msgid "The server OpenPGP private key file is writable." -msgstr "Serverio OpenPGP privataus rakto failas yra rašomas." +msgid "The database cannot be installed" +msgstr "Duomenų bazės įdiegti negalima" -msgid "The server OpenPGP private key file is not writable." -msgstr "Serverio OpenPGP privataus rakto failas neįrašomas." +msgid "There was a problem creating the first user" +msgstr "Kuriant pirmąjį naudotoją kilo problema" + +msgid "There was a problem creating the registration token" +msgstr "Kuriant registracijos prieigos raktą kilo problema" msgid "Create your user account!" msgstr "Susikurkite savo vartotojo paskyrą!" @@ -3442,18 +3997,9 @@ msgstr "URL (universalaus adreso) perrašymas nėra tinkamai sukonfigūruotas j msgid "GPG is configured correctly." msgstr "GPG sukonfigūruotas teisingai." -msgid "GPG Configuration" -msgstr "GPG konfigūracija" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "SSL prieiga įjungta." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "SSL prieiga neįjungta. Vis tiek galite tęsti, bet labai rekomenduojama prieš tęsiant sukonfigūruoti žiniatinklio serverį naudoti HTTPS." - msgid "Start configuration" msgstr "Pradėti konfigūraciją" @@ -3544,9 +4090,6 @@ msgstr "Sveikatos patikrinimas" msgid "Passbolt API Status" msgstr "\"Passbolt\" API (aplikacijų programavimo sąsaja) statusas" -msgid "SSL access is not enabled." -msgstr "SSL prieiga neįjungta." - msgid "Group manager" msgstr "Grupės vadovas" diff --git a/resources/locales/nl_NL/default.po b/resources/locales/nl_NL/default.po index 0592c0679b..28b2c085f2 100644 --- a/resources/locales/nl_NL/default.po +++ b/resources/locales/nl_NL/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:57\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Dutch\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Validatie van groep {0} is geslaagd" msgid "Could not validate group user data." msgstr "Gebruikersgegevens van de groep konden niet worden gevalideerd." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "ongedefinieerd" + +msgid "Could not connect to github repository" +msgstr "Kan geen verbinding maken met het GitHub-depot" + +msgid "Could not read tag information on github repository" +msgstr "De labelinformatie op het GitHub-depot kon niet gelezen worden" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "je kunt proberen:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Database" + +msgid "GPG Configuration" +msgstr "GPG-configuratie" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "SSL-toegang is ingeschakeld." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "SSL-toegang is niet ingeschakeld. Je kunt nog steeds doorgaan, maar het wordt sterk aanbevolen dat je je webserver configureert om HTTPS te gebruiken voordat je verdergaat." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Gegevens van de subsleutel konden niet worden gevalideerd." @@ -1450,15 +1981,6 @@ msgstr "Validatie is geslaagd voor gebruiker {0}" msgid "The directory {0} cannot be deleted" msgstr "De directory {0} kan niet worden verwijderd" -msgid "Database connection failed" -msgstr "" - -msgid "Could not connect to github repository" -msgstr "Kan geen verbinding maken met het GitHub-depot" - -msgid "Could not read tag information on github repository" -msgstr "De labelinformatie op het GitHub-depot kon niet gelezen worden" - msgid "The key {0} cannot be used to encrypt." msgstr "Sleutel {0} kan niet worden gebruikt om te versleutelen." @@ -1849,6 +2371,21 @@ msgstr "De persoonlijke JWT-sleutel moet minstens {0} bytes lang zijn." msgid "The configuration {0} is not correctly set." msgstr "De configuratie van {0} is niet juist ingesteld." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Het vernieuwingstoken moet een geldige UUID zijn." @@ -3034,29 +3571,53 @@ msgstr "" msgid "The client should be a valid IP or a valid domain." msgstr "" -msgid "Could not validate the smtp settings." -msgstr "De smtp-instellingen konden niet gevalideerd worden." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "De smtp-instellingen die in de database staan, konden niet gevalideerd worden." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "De OpenPGP-serversleutel kan niet worden gebruikt om de SMTP-instellingen die in de database zijn opgeslagen te ontsleutelen." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Om dit probleem te verhelpen, moet je de SMTP-server opnieuw configureren." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "niet gevonden" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "database" msgid "env variables" msgstr "omgevingsvariabelen" -msgid "undefined" -msgstr "ongedefinieerd" +msgid "Could not validate the smtp settings." +msgstr "De smtp-instellingen konden niet gevalideerd worden." + +msgid "Could not validate the smtp settings found in database." +msgstr "De smtp-instellingen die in de database staan, konden niet gevalideerd worden." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "De OpenPGP-serversleutel kan niet worden gebruikt om de SMTP-instellingen die in de database zijn opgeslagen te ontsleutelen." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Om dit probleem te verhelpen, moet je de SMTP-server opnieuw configureren." msgid "Passbolt test email" msgstr "Passbolt test-e-mail" @@ -3088,9 +3649,6 @@ msgstr "Systeemcontrole" msgid "Subscription key" msgstr "Abonnementssleutel" -msgid "Database" -msgstr "Database" - msgid "Server keys" msgstr "Serversleutels" @@ -3205,18 +3763,6 @@ msgstr "Een geforceerde SSL-status is vereist." msgid "The force ssl setting should be a valid boolean." msgstr "De geforceerde SSL-instelling moet een geldige Boolean zijn." -msgid "The database schema does not match the one expected" -msgstr "Het databaseschema komt niet overeen met het verwachte schema" - -msgid "The database cannot be installed" -msgstr "De database kan niet geïnstalleerd worden" - -msgid "There was a problem creating the first user" -msgstr "Er is een fout opgetreden bij het aanmaken van de eerste gebruiker" - -msgid "There was a problem creating the registration token" -msgstr "Er is een fout opgetreden bij het aanmaken van het registratietoken" - msgid "The passbolt config is writable." msgstr "De configuratie van Passbolt is beschrijfbaar." @@ -3226,8 +3772,14 @@ msgstr "De configuratie van Passbolt is niet beschrijfbaar." msgid "Ensure the file " msgstr "Waarborg het bestand " -msgid "you can try:" -msgstr "je kunt proberen:" +msgid "The server OpenPGP private key file is writable." +msgstr "Het persoonlijke OpenPGP-sleutelbestand van de server is beschrijfbaar." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Het persoonlijke OpenPGP-sleutelbestand van de server is niet beschrijfbaar." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Zorg ervoor dat de webserver-gebruiker het bestand {0} kan beschrijven." msgid "The server OpenPGP public key file is writable." msgstr "Het openbare OpenPGP-sleutelbestand van de server is beschrijfbaar." @@ -3235,14 +3787,17 @@ msgstr "Het openbare OpenPGP-sleutelbestand van de server is beschrijfbaar." msgid "The server OpenPGP public key file is not writable." msgstr "Het openbare OpenPGP-sleutelbestand van de server is niet beschrijfbaar." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Zorg ervoor dat de webserver-gebruiker het bestand {0} kan beschrijven." +msgid "The database schema does not match the one expected" +msgstr "Het databaseschema komt niet overeen met het verwachte schema" -msgid "The server OpenPGP private key file is writable." -msgstr "Het persoonlijke OpenPGP-sleutelbestand van de server is beschrijfbaar." +msgid "The database cannot be installed" +msgstr "De database kan niet geïnstalleerd worden" -msgid "The server OpenPGP private key file is not writable." -msgstr "Het persoonlijke OpenPGP-sleutelbestand van de server is niet beschrijfbaar." +msgid "There was a problem creating the first user" +msgstr "Er is een fout opgetreden bij het aanmaken van de eerste gebruiker" + +msgid "There was a problem creating the registration token" +msgstr "Er is een fout opgetreden bij het aanmaken van het registratietoken" msgid "Create your user account!" msgstr "Maak je gebruikersaccount aan!" @@ -3442,18 +3997,9 @@ msgstr "Het herschrijven van een URL is niet correct geconfigureerd op de server msgid "GPG is configured correctly." msgstr "GPG is correct geconfigureerd." -msgid "GPG Configuration" -msgstr "GPG-configuratie" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "SSL-toegang is ingeschakeld." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "SSL-toegang is niet ingeschakeld. Je kunt nog steeds doorgaan, maar het wordt sterk aanbevolen dat je je webserver configureert om HTTPS te gebruiken voordat je verdergaat." - msgid "Start configuration" msgstr "Begin met de configuratie" @@ -3544,9 +4090,6 @@ msgstr "Gezondheidscontrole" msgid "Passbolt API Status" msgstr "Passbolt's API-status" -msgid "SSL access is not enabled." -msgstr "SSL-toegang is niet ingeschakeld." - msgid "Group manager" msgstr "Groepsbeheerder" diff --git a/resources/locales/pl_PL/default.po b/resources/locales/pl_PL/default.po index 853877d746..760e934f91 100644 --- a/resources/locales/pl_PL/default.po +++ b/resources/locales/pl_PL/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:57\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Polish\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Weryfikacja grupy {0} powiodła się" msgid "Could not validate group user data." msgstr "Nie udało się zweryfikować danych użytkownika grupy." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "niezdefiniowany" + +msgid "Could not connect to github repository" +msgstr "Nie udało się połączyć z repozytorium githud" + +msgid "Could not read tag information on github repository" +msgstr "Nie udało się odczytać informacji o tagu w repozytorium github" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "możesz spróbować:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Baza danych" + +msgid "GPG Configuration" +msgstr "Konfiguracja GPG" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "Dostęp SSL jest włączony." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "Nie włączono dostępu do SSL. Możesz działać dalej, ale najpierw zalecamy skonfigurować Twój serwer WWW pod obsługę protokołu HTTPS." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Nie udało się zweryfikować danych podklucza." @@ -1450,15 +1981,6 @@ msgstr "Weryfikacja użytkownika {0} powiodła się" msgid "The directory {0} cannot be deleted" msgstr "Katalog {0} nie może zostać usunięty" -msgid "Database connection failed" -msgstr "Połączenie z bazą danych nie powiodło się" - -msgid "Could not connect to github repository" -msgstr "Nie udało się połączyć z repozytorium githud" - -msgid "Could not read tag information on github repository" -msgstr "Nie udało się odczytać informacji o tagu w repozytorium github" - msgid "The key {0} cannot be used to encrypt." msgstr "Klucz {0} nie może być użyty do szyfrowania." @@ -1849,6 +2371,21 @@ msgstr "Klucz prywatny JWT powinien mieć długość przynajmniej {0} bajtów." msgid "The configuration {0} is not correctly set." msgstr "Nie ustawiono poprawnie konfiguracji {0}." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Token odświeżania powinien być prawidłowym UUID." @@ -3034,29 +3571,53 @@ msgstr "Wyłączono endpointy ustawień SMTP." msgid "The client should be a valid IP or a valid domain." msgstr "Klient powinien być prawidłowym adresem IP lub prawidłową domeną." -msgid "Could not validate the smtp settings." -msgstr "Nie można zweryfikować ustawień smtp." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "Nie można zweryfikować ustawień SMTP znalezionych w bazie danych." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "Klucz serwera OpenPGP nie może być użyty do odszyfrowania ustawień SMTP przechowywanych w bazie danych." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Aby rozwiązać ten problem, musisz ponownie skonfigurować serwer SMTP." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "nie znaleziono" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "baza danych" msgid "env variables" msgstr "zmienne środowiskowe" -msgid "undefined" -msgstr "niezdefiniowany" +msgid "Could not validate the smtp settings." +msgstr "Nie można zweryfikować ustawień smtp." + +msgid "Could not validate the smtp settings found in database." +msgstr "Nie można zweryfikować ustawień SMTP znalezionych w bazie danych." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "Klucz serwera OpenPGP nie może być użyty do odszyfrowania ustawień SMTP przechowywanych w bazie danych." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Aby rozwiązać ten problem, musisz ponownie skonfigurować serwer SMTP." msgid "Passbolt test email" msgstr "Wiadomość testowa z passbolt" @@ -3088,9 +3649,6 @@ msgstr "Weryfikacja systemu" msgid "Subscription key" msgstr "Klucz subskrypcji" -msgid "Database" -msgstr "Baza danych" - msgid "Server keys" msgstr "Klucze serwera" @@ -3205,18 +3763,6 @@ msgstr "Status wymuszania SSL jest wymagany." msgid "The force ssl setting should be a valid boolean." msgstr "Ustawienie wymuszanego SSL powinno być prawidłową wartością logiczną." -msgid "The database schema does not match the one expected" -msgstr "Schemat bazy danych nie pasuje do oczekiwanego" - -msgid "The database cannot be installed" -msgstr "Nie można zainstalować bazy danych" - -msgid "There was a problem creating the first user" -msgstr "Wystąpił problem podczas tworzenia pierwszego użytkownika" - -msgid "There was a problem creating the registration token" -msgstr "Wystąpił problem podczas tworzenia tokenu rejestracji" - msgid "The passbolt config is writable." msgstr "Konfiguracja passbolt jest zapisywalna." @@ -3226,8 +3772,14 @@ msgstr "Konfiguracja passbolt nie jest zapisywalna." msgid "Ensure the file " msgstr "Upewnij się, że plik " -msgid "you can try:" -msgstr "możesz spróbować:" +msgid "The server OpenPGP private key file is writable." +msgstr "Plik prywatnego klucza Open PGP do serwera jest zapisywalny." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Plik prywatnego klucza Open PGP do serwera nie jest zapisywalny." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Upewnij się, że plik {0} jest zapisywalny przez użytkownika serwera WWW." msgid "The server OpenPGP public key file is writable." msgstr "Plik klucza publicznego OpenPGP serwera można zapisać." @@ -3235,14 +3787,17 @@ msgstr "Plik klucza publicznego OpenPGP serwera można zapisać." msgid "The server OpenPGP public key file is not writable." msgstr "Nie można zapisać pliku klucza publicznego OpenPGP serwera." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Upewnij się, że plik {0} jest zapisywalny przez użytkownika serwera WWW." +msgid "The database schema does not match the one expected" +msgstr "Schemat bazy danych nie pasuje do oczekiwanego" -msgid "The server OpenPGP private key file is writable." -msgstr "Plik prywatnego klucza Open PGP do serwera jest zapisywalny." +msgid "The database cannot be installed" +msgstr "Nie można zainstalować bazy danych" -msgid "The server OpenPGP private key file is not writable." -msgstr "Plik prywatnego klucza Open PGP do serwera nie jest zapisywalny." +msgid "There was a problem creating the first user" +msgstr "Wystąpił problem podczas tworzenia pierwszego użytkownika" + +msgid "There was a problem creating the registration token" +msgstr "Wystąpił problem podczas tworzenia tokenu rejestracji" msgid "Create your user account!" msgstr "Stwórz swoje konto użytkownika!" @@ -3442,18 +3997,9 @@ msgstr "Przepisanie adresu URL nie jest poprawnie skonfigurowane na Twoim serwer msgid "GPG is configured correctly." msgstr "GPG jest skonfigurowane poprawnie." -msgid "GPG Configuration" -msgstr "Konfiguracja GPG" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "Dostęp SSL jest włączony." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "Nie włączono dostępu do SSL. Możesz działać dalej, ale najpierw zalecamy skonfigurować Twój serwer WWW pod obsługę protokołu HTTPS." - msgid "Start configuration" msgstr "Zacznij konfigurację" @@ -3544,9 +4090,6 @@ msgstr "Kontrola" msgid "Passbolt API Status" msgstr "Status API w Passbolt" -msgid "SSL access is not enabled." -msgstr "Dostęp SSL jest wyłączony." - msgid "Group manager" msgstr "Menedżer grupy" diff --git a/resources/locales/pt_BR/default.po b/resources/locales/pt_BR/default.po index dc5c462ee7..e292bdd110 100644 --- a/resources/locales/pt_BR/default.po +++ b/resources/locales/pt_BR/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:56\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Portuguese, Brazilian\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Validação para o grupo {0}" msgid "Could not validate group user data." msgstr "Não foi possível validar os dados do usuário do grupo." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "não definido" + +msgid "Could not connect to github repository" +msgstr "Não foi possível conectar ao repositório do github" + +msgid "Could not read tag information on github repository" +msgstr "Não foi possível ler informações da etiqueta no repositório do github" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "você pode tentar:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Banco" + +msgid "GPG Configuration" +msgstr "Configuração GPG" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "O acesso ao SSL está ativado." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "O acesso SSL não está habilitado. Você ainda pode prosseguir, mas é altamente recomendável que você configure seu servidor web para usar HTTPS antes de continuar." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Não foi possível validar os dados da subchave." @@ -1450,15 +1981,6 @@ msgstr "Sucesso na validação para o usuário {0}" msgid "The directory {0} cannot be deleted" msgstr "O diretório {0} não pode ser excluído" -msgid "Database connection failed" -msgstr "Conexão com base de dados falhou" - -msgid "Could not connect to github repository" -msgstr "Não foi possível conectar ao repositório do github" - -msgid "Could not read tag information on github repository" -msgstr "Não foi possível ler informações da etiqueta no repositório do github" - msgid "The key {0} cannot be used to encrypt." msgstr "A chave {0} não pode ser usada para criptografar." @@ -1849,6 +2371,21 @@ msgstr "A chave privada JWT deve ter pelo menos {0} bytes de comprimento." msgid "The configuration {0} is not correctly set." msgstr "A configuração {0} não está definida corretamente." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "O token de atualização deve ser um UUID válido." @@ -3034,29 +3571,53 @@ msgstr "Endpoints de configurações de SMTP desativados." msgid "The client should be a valid IP or a valid domain." msgstr "O cliente deve ser um IP válido ou um domínio válido." -msgid "Could not validate the smtp settings." -msgstr "Não foi possível validar as configurações de SMTP." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "Não foi possível validar as definições de SMTP encontradas na base de dados." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "A chave do servidor OpenPGP não pode ser usada para descriptografar as configurações SMTP armazenadas em banco de dados." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Para corrigir este problema, você precisa configurar o servidor SMTP novamente." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "não encontrado" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "banco" msgid "env variables" msgstr "variáveis de ambiente" -msgid "undefined" -msgstr "não definido" +msgid "Could not validate the smtp settings." +msgstr "Não foi possível validar as configurações de SMTP." + +msgid "Could not validate the smtp settings found in database." +msgstr "Não foi possível validar as definições de SMTP encontradas na base de dados." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "A chave do servidor OpenPGP não pode ser usada para descriptografar as configurações SMTP armazenadas em banco de dados." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Para corrigir este problema, você precisa configurar o servidor SMTP novamente." msgid "Passbolt test email" msgstr "Passbolt teste e-mail" @@ -3088,9 +3649,6 @@ msgstr "Verificação do sistema" msgid "Subscription key" msgstr "Chave de assinatura" -msgid "Database" -msgstr "Banco" - msgid "Server keys" msgstr "Chaves do servidor" @@ -3205,18 +3763,6 @@ msgstr "É necessário um status ssl da força." msgid "The force ssl setting should be a valid boolean." msgstr "A configuração do ssl de força deve ser um booleano válido." -msgid "The database schema does not match the one expected" -msgstr "O esquema da base de dados não coincide com o esperado" - -msgid "The database cannot be installed" -msgstr "A base de dados não pode ser instalada" - -msgid "There was a problem creating the first user" -msgstr "Houve um problema ao criar o primeiro usuário" - -msgid "There was a problem creating the registration token" -msgstr "Houve um problema ao criar o token de registro" - msgid "The passbolt config is writable." msgstr "A configuração do passbolt é gravável." @@ -3226,8 +3772,14 @@ msgstr "A configuração do passbolt não é gravável." msgid "Ensure the file " msgstr "Certifique-se do arquivo " -msgid "you can try:" -msgstr "você pode tentar:" +msgid "The server OpenPGP private key file is writable." +msgstr "O arquivo de chave privada OpenPGP do servidor é gravável." + +msgid "The server OpenPGP private key file is not writable." +msgstr "O arquivo de chave privada OpenPGP do servidor não é gravável." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Certifique-se de que o arquivo {0} seja gravável pelo usuário do servidor da web." msgid "The server OpenPGP public key file is writable." msgstr "O arquivo de chave pública OpenPGP do servidor é gravável." @@ -3235,14 +3787,17 @@ msgstr "O arquivo de chave pública OpenPGP do servidor é gravável." msgid "The server OpenPGP public key file is not writable." msgstr "O arquivo de chave pública OpenPGP do servidor não é gravável." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Certifique-se de que o arquivo {0} seja gravável pelo usuário do servidor da web." +msgid "The database schema does not match the one expected" +msgstr "O esquema da base de dados não coincide com o esperado" -msgid "The server OpenPGP private key file is writable." -msgstr "O arquivo de chave privada OpenPGP do servidor é gravável." +msgid "The database cannot be installed" +msgstr "A base de dados não pode ser instalada" -msgid "The server OpenPGP private key file is not writable." -msgstr "O arquivo de chave privada OpenPGP do servidor não é gravável." +msgid "There was a problem creating the first user" +msgstr "Houve um problema ao criar o primeiro usuário" + +msgid "There was a problem creating the registration token" +msgstr "Houve um problema ao criar o token de registro" msgid "Create your user account!" msgstr "Crie sua conta de usuário!" @@ -3442,18 +3997,9 @@ msgstr "A reescrita de URL não está configurada corretamente no seu servidor." msgid "GPG is configured correctly." msgstr "GPG está configurado corretamente." -msgid "GPG Configuration" -msgstr "Configuração GPG" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "O acesso ao SSL está ativado." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "O acesso SSL não está habilitado. Você ainda pode prosseguir, mas é altamente recomendável que você configure seu servidor web para usar HTTPS antes de continuar." - msgid "Start configuration" msgstr "Iniciar configuração" @@ -3544,9 +4090,6 @@ msgstr "Exercícios de saúde" msgid "Passbolt API Status" msgstr "Passbolt API Status" -msgid "SSL access is not enabled." -msgstr "O acesso SSL não está habilitado." - msgid "Group manager" msgstr "Gerenciador de grupo" diff --git a/resources/locales/ro_RO/default.po b/resources/locales/ro_RO/default.po index bf0565ec8e..ed559c1868 100644 --- a/resources/locales/ro_RO/default.po +++ b/resources/locales/ro_RO/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:56\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Romanian\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Validare reușită pentru grupul {0}" msgid "Could not validate group user data." msgstr "Nu s-au putut valida datele de utilizator grup." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "" + +msgid "Could not connect to github repository" +msgstr "Nu m-am putut conecta la repo-ul GitHub" + +msgid "Could not read tag information on github repository" +msgstr "Nu s-au putut citi informațiile tag-ului in repo-ul GitHub" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "puteţi încerca:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Baza de date" + +msgid "GPG Configuration" +msgstr "Configurare GPG" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "Accesul SSL nu este activat." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "Accesul SSL nu este activat. Puteți continua, dar este recomandat să configurați serverul web pentru a utiliza HTTPS înainte de a continua." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Nu s-au putut valida datele sub-cheii." @@ -1450,15 +1981,6 @@ msgstr "Validare reușită pentru utilizatorul {0}" msgid "The directory {0} cannot be deleted" msgstr "" -msgid "Database connection failed" -msgstr "" - -msgid "Could not connect to github repository" -msgstr "Nu m-am putut conecta la repo-ul GitHub" - -msgid "Could not read tag information on github repository" -msgstr "Nu s-au putut citi informațiile tag-ului in repo-ul GitHub" - msgid "The key {0} cannot be used to encrypt." msgstr "Cheia {0} nu poate fi folosită pentru criptare." @@ -1849,6 +2371,21 @@ msgstr "Cheia privată JWT trebuie să fie de cel puțin {0} octeți." msgid "The configuration {0} is not correctly set." msgstr "Configurația {0} nu este setată corect." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Token-ul de reîmprospătare trebuie să fie un UUID valid." @@ -3034,28 +3571,52 @@ msgstr "" msgid "The client should be a valid IP or a valid domain." msgstr "" -msgid "Could not validate the smtp settings." +msgid "SMTP Settings coherent. You may send a test email to validate them." msgstr "" -msgid "Could not validate the smtp settings found in database." +msgid "SMTP Setting errors: {0}" msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgid "The {0} plugin endpoints are disabled." msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." msgstr "" msgid "not found" msgstr "" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "baza de date" msgid "env variables" msgstr "" -msgid "undefined" +msgid "Could not validate the smtp settings." +msgstr "" + +msgid "Could not validate the smtp settings found in database." +msgstr "" + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "" + +msgid "To fix this problem, you need to configure the SMTP server again." msgstr "" msgid "Passbolt test email" @@ -3088,9 +3649,6 @@ msgstr "Verificare sistem" msgid "Subscription key" msgstr "Cheia de abonare" -msgid "Database" -msgstr "Baza de date" - msgid "Server keys" msgstr "Cheile serverului" @@ -3205,18 +3763,6 @@ msgstr "Este necesar un status pentru forțează SSL." msgid "The force ssl setting should be a valid boolean." msgstr "Setarea pentru forțează SSL ar trebui să fie un boolean valid." -msgid "The database schema does not match the one expected" -msgstr "Schema bazei de date nu corespunde cu cea așteptată" - -msgid "The database cannot be installed" -msgstr "Baza de date nu a putut fi instalată" - -msgid "There was a problem creating the first user" -msgstr "A apărut o eroare la crearea primului utilizator" - -msgid "There was a problem creating the registration token" -msgstr "A apărut o eroare la crearea token-ului de înregistrare" - msgid "The passbolt config is writable." msgstr "Configurația Passbolt permite scrierea." @@ -3226,8 +3772,14 @@ msgstr "Configurația Passbolt nu permite scrierea." msgid "Ensure the file " msgstr "Asigurați-vă că fișierul " -msgid "you can try:" -msgstr "puteţi încerca:" +msgid "The server OpenPGP private key file is writable." +msgstr "Fișierul cheii private OpenPGP a server-ului poate fi scris." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Fișierul cheii private OpenPGP a server-ului nu poate fi scris." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Asigurați-vă că fișierul {0} poate fi scris de către user-ul webserverului." msgid "The server OpenPGP public key file is writable." msgstr "Fișierul cheii publice OpenPGP a server-ului poate fi scris." @@ -3235,14 +3787,17 @@ msgstr "Fișierul cheii publice OpenPGP a server-ului poate fi scris." msgid "The server OpenPGP public key file is not writable." msgstr "Fișierul cheii publice OpenPGP a server-ului nu poate fi scris." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Asigurați-vă că fișierul {0} poate fi scris de către user-ul webserverului." +msgid "The database schema does not match the one expected" +msgstr "Schema bazei de date nu corespunde cu cea așteptată" -msgid "The server OpenPGP private key file is writable." -msgstr "Fișierul cheii private OpenPGP a server-ului poate fi scris." +msgid "The database cannot be installed" +msgstr "Baza de date nu a putut fi instalată" -msgid "The server OpenPGP private key file is not writable." -msgstr "Fișierul cheii private OpenPGP a server-ului nu poate fi scris." +msgid "There was a problem creating the first user" +msgstr "A apărut o eroare la crearea primului utilizator" + +msgid "There was a problem creating the registration token" +msgstr "A apărut o eroare la crearea token-ului de înregistrare" msgid "Create your user account!" msgstr "Creați-vă contul de utilizator!" @@ -3442,18 +3997,9 @@ msgstr "Rescrierea de URL-uri nu este configurată corect pe serverul dvs." msgid "GPG is configured correctly." msgstr "GPG este configurat corect." -msgid "GPG Configuration" -msgstr "Configurare GPG" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "Accesul SSL nu este activat." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "Accesul SSL nu este activat. Puteți continua, dar este recomandat să configurați serverul web pentru a utiliza HTTPS înainte de a continua." - msgid "Start configuration" msgstr "Începe configurarea" @@ -3544,9 +4090,6 @@ msgstr "Verificare stare sistem" msgid "Passbolt API Status" msgstr "Status API Passbolt" -msgid "SSL access is not enabled." -msgstr "Accesul SSL nu este activat." - msgid "Group manager" msgstr "Manager de grup" diff --git a/resources/locales/ru_RU/default.po b/resources/locales/ru_RU/default.po index 3a07344750..507a1b2269 100644 --- a/resources/locales/ru_RU/default.po +++ b/resources/locales/ru_RU/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:56\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Russian\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Успешная проверка для группы {0}" msgid "Could not validate group user data." msgstr "Не удалось проверить данные пользователя группы." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "неопределённый" + +msgid "Could not connect to github repository" +msgstr "Не удалось подключиться к репозиторию github" + +msgid "Could not read tag information on github repository" +msgstr "Не удалось прочитать информацию о тегах в репозитории github." + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "можешь попробовать:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "База данных" + +msgid "GPG Configuration" +msgstr "Конфигурация GPG" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "SSL-доступ включен." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "SSL-доступ не включен. Вы все еще можете продолжить, но настоятельно рекомендуется настроить веб-сервер на использование HTTPS, прежде чем продолжить." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "Не удалось проверить данные подключей." @@ -1450,15 +1981,6 @@ msgstr "Успешная проверка для пользователя {0}" msgid "The directory {0} cannot be deleted" msgstr "Каталог {0} не может быть удален" -msgid "Database connection failed" -msgstr "Ошибка подключения к базе данных" - -msgid "Could not connect to github repository" -msgstr "Не удалось подключиться к репозиторию github" - -msgid "Could not read tag information on github repository" -msgstr "Не удалось прочитать информацию о тегах в репозитории github." - msgid "The key {0} cannot be used to encrypt." msgstr "Ключ {0} нельзя использовать для шифрования." @@ -1849,6 +2371,21 @@ msgstr "Закрытый ключ JWT должен иметь длину не м msgid "The configuration {0} is not correctly set." msgstr "Конфигурация {0} задана неправильно." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Токен обновления должен быть допустимым UUID." @@ -3034,29 +3571,53 @@ msgstr "Конечные точки настроек SMTP отключены." msgid "The client should be a valid IP or a valid domain." msgstr "Клиент должен быть действительным IP или действительным доменом." -msgid "Could not validate the smtp settings." -msgstr "Не удалось проверить настройки smtp." +msgid "SMTP Settings coherent. You may send a test email to validate them." +msgstr "" -msgid "Could not validate the smtp settings found in database." -msgstr "Не удалось проверить настройки smtp, найденные в базе данных." +msgid "SMTP Setting errors: {0}" +msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." -msgstr "Ключ сервера OpenPGP не может быть использован для расшифровки настроек SMTP, хранящихся в базе данных." +msgid "The {0} plugin endpoints are disabled." +msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." -msgstr "Чтобы устранить эту проблему, вам необходимо снова настроить SMTP-сервер." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." +msgstr "" msgid "not found" msgstr "не найдено" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "база данных" msgid "env variables" msgstr "переменные среды" -msgid "undefined" -msgstr "неопределённый" +msgid "Could not validate the smtp settings." +msgstr "Не удалось проверить настройки smtp." + +msgid "Could not validate the smtp settings found in database." +msgstr "Не удалось проверить настройки smtp, найденные в базе данных." + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "Ключ сервера OpenPGP не может быть использован для расшифровки настроек SMTP, хранящихся в базе данных." + +msgid "To fix this problem, you need to configure the SMTP server again." +msgstr "Чтобы устранить эту проблему, вам необходимо снова настроить SMTP-сервер." msgid "Passbolt test email" msgstr "Тестовая электронная почта Passbolt" @@ -3088,9 +3649,6 @@ msgstr "Проверка системы" msgid "Subscription key" msgstr "Ключ подписки" -msgid "Database" -msgstr "База данных" - msgid "Server keys" msgstr "Ключи сервера" @@ -3205,18 +3763,6 @@ msgstr "Требуется принудительный статус ssl." msgid "The force ssl setting should be a valid boolean." msgstr "Параметр force ssl должен быть допустимым логическим значением." -msgid "The database schema does not match the one expected" -msgstr "Схема базы данных не соответствует ожидаемой" - -msgid "The database cannot be installed" -msgstr "База данных не может быть установлена" - -msgid "There was a problem creating the first user" -msgstr "Не удалось создать первого пользователя" - -msgid "There was a problem creating the registration token" -msgstr "Возникла проблема с созданием токена регистрации." - msgid "The passbolt config is writable." msgstr "Конфигурация passbolt доступна для записи." @@ -3226,8 +3772,14 @@ msgstr "Конфигурация passbolt недоступна для запис msgid "Ensure the file " msgstr "Убедитесь, что файл" -msgid "you can try:" -msgstr "можешь попробовать:" +msgid "The server OpenPGP private key file is writable." +msgstr "Файл закрытого ключа сервера OpenPGP доступен для записи." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Файл закрытого ключа OpenPGP сервера недоступен для записи." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Убедитесь, что файл {0} доступен для записи пользователю веб-сервера." msgid "The server OpenPGP public key file is writable." msgstr "Файл открытого ключа сервера OpenPGP доступен для записи." @@ -3235,14 +3787,17 @@ msgstr "Файл открытого ключа сервера OpenPGP досту msgid "The server OpenPGP public key file is not writable." msgstr "Файл открытого ключа OpenPGP сервера недоступен для записи." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Убедитесь, что файл {0} доступен для записи пользователю веб-сервера." +msgid "The database schema does not match the one expected" +msgstr "Схема базы данных не соответствует ожидаемой" -msgid "The server OpenPGP private key file is writable." -msgstr "Файл закрытого ключа сервера OpenPGP доступен для записи." +msgid "The database cannot be installed" +msgstr "База данных не может быть установлена" -msgid "The server OpenPGP private key file is not writable." -msgstr "Файл закрытого ключа OpenPGP сервера недоступен для записи." +msgid "There was a problem creating the first user" +msgstr "Не удалось создать первого пользователя" + +msgid "There was a problem creating the registration token" +msgstr "Возникла проблема с созданием токена регистрации." msgid "Create your user account!" msgstr "Создайте свою учетную запись пользователя!" @@ -3442,18 +3997,9 @@ msgstr "Перезапись URL неправильно настроена на msgid "GPG is configured correctly." msgstr "GPG настроен правильно." -msgid "GPG Configuration" -msgstr "Конфигурация GPG" - msgid "SSL" msgstr "SSL-сертификат" -msgid "SSL access is enabled." -msgstr "SSL-доступ включен." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "SSL-доступ не включен. Вы все еще можете продолжить, но настоятельно рекомендуется настроить веб-сервер на использование HTTPS, прежде чем продолжить." - msgid "Start configuration" msgstr "Начать настройку" @@ -3544,9 +4090,6 @@ msgstr "Проверки здоровья" msgid "Passbolt API Status" msgstr "Статус Passbolt API" -msgid "SSL access is not enabled." -msgstr "SSL-доступ не включен." - msgid "Group manager" msgstr "Менеджер группы" diff --git a/resources/locales/sv_SE/default.po b/resources/locales/sv_SE/default.po index 1c2547410c..cb224c1ae9 100644 --- a/resources/locales/sv_SE/default.po +++ b/resources/locales/sv_SE/default.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" -"POT-Creation-Date: 2024-04-11 09:45+0000\n" -"PO-Revision-Date: 2024-04-11 12:57\n" +"POT-Creation-Date: 2024-04-24 04:35+0000\n" +"PO-Revision-Date: 2024-04-24 14:20\n" "Last-Translator: NAME \n" "Language-Team: Swedish\n" "MIME-Version: 1.0\n" @@ -1240,6 +1240,537 @@ msgstr "Validering lyckades för grupp {0}" msgid "Could not validate group user data." msgstr "Kunde inte validera användardata för grupp." +msgid "All email notifications will be sent." +msgstr "" + +msgid "Some email notifications are disabled by the administrator." +msgstr "" + +msgid "Host availability will be checked." +msgstr "" + +msgid "Host availability checking is disabled." +msgstr "" + +msgid "Make sure this instance is not publicly available on the internet." +msgstr "" + +msgid "Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true." +msgstr "" + +msgid "Or set passbolt.email.validate.mx to true in {0}." +msgstr "" + +msgid "Serving the compiled version of the javascript app." +msgstr "" + +msgid "Using non-compiled Javascript. Passbolt will be slower." +msgstr "" + +msgid "Set passbolt.js.build to production in {0}" +msgstr "" + +msgid "undefined" +msgstr "" + +msgid "Could not connect to github repository" +msgstr "Kunde inte ansluta till github repository" + +msgid "Could not read tag information on github repository" +msgstr "Kunde inte läsa tagginformation på github repository" + +msgid "Using latest passbolt version ({0})." +msgstr "" + +msgid "Could connect to passbolt repository to check versions." +msgstr "" + +msgid "This installation is not up to date. Currently using {0} and it should be {1}." +msgstr "" + +msgid "Could not connect to passbolt repository to check versions" +msgstr "" + +msgid "It is not possible check if your version is up to date." +msgstr "" + +msgid "See https://www.passbolt.com/help/tech/update" +msgstr "" + +msgid "Check the network configuration to allow this script to check for updates." +msgstr "" + +msgid "Search engine robots are told not to index content." +msgstr "" + +msgid "Search engine robots are not told not to index content." +msgstr "" + +msgid "Set passbolt.meta.robots to false in {0}." +msgstr "" + +msgid "Selenium API endpoints are disabled." +msgstr "" + +msgid "Selenium API endpoints are active. This setting should be used for testing only." +msgstr "" + +msgid "Set passbolt.selenium.active to false in {0}." +msgstr "" + +msgid "The Self Registration plugin is enabled." +msgstr "" + +msgid "The Self Registration plugin is disabled." +msgstr "" + +msgid "Enable the plugin in order to define self registration settings." +msgstr "" + +msgid "Registration is closed, only administrators can add users." +msgstr "" + +msgid "The self registration provider is: {0}." +msgstr "" + +msgid "The deprecated self registration public setting was not found in {0}." +msgstr "" + +msgid "The deprecated self registration public setting was found in {0}." +msgstr "" + +msgid "You may remove the \"passbolt.registration.public\" setting." +msgstr "" + +msgid "Passbolt is configured to force SSL use." +msgstr "" + +msgid "Passbolt is not configured to force SSL use." +msgstr "" + +msgid "Set passbolt.ssl.force to true in {0}." +msgstr "" + +msgid "App.fullBaseUrl is set to HTTPS." +msgstr "" + +msgid "App.fullBaseUrl is not set to HTTPS." +msgstr "" + +msgid "Check App.fullBaseUrl url scheme in {0}." +msgstr "" + +msgid "The application config file is present" +msgstr "" + +msgid "The application config file is missing in {0}" +msgstr "" + +msgid "Copy {0} to {1}" +msgstr "" + +msgid "The passbolt config file is present" +msgstr "" + +msgid "The passbolt config file is missing in {0}" +msgstr "" + +msgid "The passbolt config file is not required if passbolt is configured with environment variables" +msgstr "" + +msgid "Cache is working." +msgstr "" + +msgid "Cache is NOT working." +msgstr "" + +msgid "Check the settings in {0}" +msgstr "" + +msgid "Debug mode is off." +msgstr "" + +msgid "Debug mode is on." +msgstr "" + +msgid "Set debug to false in {0}" +msgstr "" + +msgid "Full base url is set to {0}" +msgstr "" + +msgid "Full base url is not set. The application is using: {0}." +msgstr "" + +msgid "Edit App.fullBaseUrl in {0}" +msgstr "" + +msgid "/healthcheck/status is reachable." +msgstr "" + +msgid "Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl" +msgstr "" + +msgid "Check that the domain name is correct in {0}" +msgstr "" + +msgid "Check the network settings" +msgstr "" + +msgid "Unique value set for security.salt" +msgstr "" + +msgid "Default value found for security.salt" +msgstr "" + +msgid "Edit the security.salt in {0}" +msgstr "" + +msgid "App.fullBaseUrl validation OK." +msgstr "" + +msgid "App.fullBaseUrl does not validate. {0}." +msgstr "" + +msgid "Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt" +msgstr "" + +msgid "The application is able to connect to the database" +msgstr "" + +msgid "The driver defined in the database configuration is not supported." +msgstr "" + +msgid "The application is not able to connect to the database." +msgstr "" + +msgid "Ensure that the driver defined in {0} is one of the following: {1}." +msgstr "" + +msgid "Double check the host, database name, username and password in {0}." +msgstr "" + +msgid "Make sure the database exists and is accessible for the given database user." +msgstr "" + +msgid "Some default content is present." +msgstr "" + +msgid "No default content found." +msgstr "" + +msgid "Run the install script to install the database tables" +msgstr "" + +msgid "The database schema up to date." +msgstr "" + +msgid "The database schema is not up to date." +msgstr "" + +msgid "Run the migration scripts:" +msgstr "" + +msgid "{0} tables found." +msgstr "" + +msgid "No table found." +msgstr "" + +msgid "GD or Imagick extension is installed." +msgstr "" + +msgid "You must enable the gd or imagick extensions to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.image.php" +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.imagick.php" +msgstr "" + +msgid "Intl extension is installed." +msgstr "" + +msgid "You must enable the intl extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.intl.php" +msgstr "" + +msgid "The logs directory and its content are writable." +msgstr "" + +msgid "The logs directory and its content are not writable." +msgstr "" + +msgid "Ensure the logs directory and its content are writable by the user the webserver user." +msgstr "" + +msgid "you can try:" +msgstr "du kan prova:" + +msgid "Mbstring extension is installed." +msgstr "" + +msgid "You must enable the mbstring extension to use Passbolt." +msgstr "" + +msgid "See. https://secure.php.net/manual/en/book.mbstring.php" +msgstr "" + +msgid "PHP version is {0} or above." +msgstr "" + +msgid "PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment." +msgstr "" + +msgid "PCRE compiled with unicode support." +msgstr "" + +msgid "PCRE has not been compiled with Unicode support." +msgstr "" + +msgid "Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring." +msgstr "" + +msgid "PHP version {0}." +msgstr "" + +msgid "PHP version is too low, passbolt need PHP {0} or higher." +msgstr "" + +msgid "The temporary directory and its content are writable and not executable." +msgstr "" + +msgid "The temporary directory and its content are not writable, or are executable." +msgstr "" + +msgid "Ensure the temporary directory and its content are writable by the webserver user." +msgstr "" + +msgid "The private key can be used to decrypt a message." +msgstr "" + +msgid "The private key cannot be used to decrypt a message" +msgstr "" + +msgid "The private key can be used to decrypt and verify a message." +msgstr "" + +msgid "The private key cannot be used to decrypt and verify a message" +msgstr "" + +msgid "The public key can be used to encrypt a message." +msgstr "" + +msgid "The public key cannot be used to encrypt a message" +msgstr "" + +msgid "Make sure that the server private key is valid and that there is no passphrase." +msgstr "" + +msgid "Make sure you imported the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public and private keys can be used to encrypt and sign a message." +msgstr "" + +msgid "The public and private keys cannot be used to encrypt and sign a message" +msgstr "" + +msgid "The private key can be used to sign a message." +msgstr "" + +msgid "The private key cannot be used to sign a message" +msgstr "" + +msgid "The public key can be used to verify a signature." +msgstr "" + +msgid "The public key cannot be used to verify a signature." +msgstr "" + +msgid "The server key fingerprint matches the one defined in {0}." +msgstr "" + +msgid "The server key fingerprint doesn't match the one defined in {0}." +msgstr "" + +msgid "Double check the key fingerprint, example: " +msgstr "" + +msgid "SERVER_KEY_EMAIL: The email you used when you generated the server key." +msgstr "" + +msgid "See. https://www.passbolt.com/help/tech/install#toc_gpg" +msgstr "" + +msgid "The server private key format is Gopengpg compatible." +msgstr "" + +msgid "The server private key format is not Gopengpg compatible." +msgstr "" + +msgid "The server public key format is Gopengpg compatible." +msgstr "" + +msgid "The server public key format is not Gopengpg compatible." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}." +msgstr "" + +msgid "The environment variable GNUPGHOME is set to {0}, but the directory does not exist." +msgstr "" + +msgid "Ensure the keyring location exists and is accessible by the webserver user." +msgstr "" + +msgid "You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}." +msgstr "" + +msgid "The directory {0} containing the keyring is writable by the webserver user." +msgstr "" + +msgid "The directory {0} containing the keyring is not writable by the webserver user." +msgstr "" + +msgid "Ensure the keyring location is accessible by the webserver user." +msgstr "" + +msgid "The server OpenPGP key is not the default one." +msgstr "" + +msgid "Do not use the default OpenPGP key for the server." +msgstr "" + +msgid "The server OpenPGP key is not set." +msgstr "" + +msgid "Create a key, export it and add the fingerprint to {0}" +msgstr "" + +msgid "PHP GPG Module is installed and loaded." +msgstr "" + +msgid "PHP GPG Module is not installed or loaded." +msgstr "" + +msgid "Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php" +msgstr "" + +msgid "Make sure to add extension=gnupg.so in php ini files for both php-cli and php." +msgstr "" + +msgid "The private key file is defined in {0} and readable." +msgstr "" + +msgid "The private key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}." +msgstr "" + +msgid "Ensure there is a private key armored block in the key file." +msgstr "" + +msgid "Ensure the private key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "There is a valid email id defined for the server key." +msgstr "" + +msgid "The server key does not have a valid email id." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is in the keyring." +msgstr "" + +msgid "The server public key defined in the {0} (or environment variables) is not in the keyring" +msgstr "" + +msgid "Import the private server key in the keyring of the webserver user." +msgstr "" + +msgid "The public key file is defined in {0} and readable." +msgstr "" + +msgid "The public key file is not defined in {0} or not readable." +msgstr "" + +msgid "Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}." +msgstr "" + +msgid "Ensure there is a public key armored block in the key file." +msgstr "" + +msgid "Ensure the public key defined in {0} exists and is accessible by the webserver user." +msgstr "" + +msgid "Environment" +msgstr "" + +msgid "Config files" +msgstr "" + +msgid "Core config" +msgstr "" + +msgid "SMTP settings" +msgstr "" + +msgid "Application configuration" +msgstr "" + +msgid "Database" +msgstr "Databas" + +msgid "GPG Configuration" +msgstr "Konfiguration av GPG" + +msgid "JWT Authentication" +msgstr "" + +msgid "SSL Certificate" +msgstr "" + +msgid "The {0} plugin is enabled." +msgstr "" + +msgid "The {0} plugin is disabled." +msgstr "" + +msgid "Set the environment variable {0} to true" +msgstr "" + +msgid "Enable the plugin in order to define SMTP settings in the database." +msgstr "" + +msgid "Hostname is matching in SSL certificate." +msgstr "" + +msgid "Hostname does not match when validating certificates." +msgstr "" + +msgid "SSL access is enabled." +msgstr "SSL-åtkomst är aktiverad." + +msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." +msgstr "SSL-åtkomst är inte aktiverad. Du kan fortfarande gå vidare men det rekommenderas starkt att du konfigurerar din webbserver för att använda HTTPS innan du fortsätter." + +msgid "Not using a self-signed certificate." +msgstr "" + +msgid "Using a self-signed certificate." +msgstr "" + +msgid "SSL peer certificate validates." +msgstr "" + +msgid "SSL peer certificate does not validate." +msgstr "" + msgid "Could not validate sub key data." msgstr "" @@ -1450,15 +1981,6 @@ msgstr "Validering lyckades för användare {0}" msgid "The directory {0} cannot be deleted" msgstr "" -msgid "Database connection failed" -msgstr "" - -msgid "Could not connect to github repository" -msgstr "Kunde inte ansluta till github repository" - -msgid "Could not read tag information on github repository" -msgstr "Kunde inte läsa tagginformation på github repository" - msgid "The key {0} cannot be used to encrypt." msgstr "Nyckeln {0} kan inte användas för att kryptera." @@ -1849,6 +2371,21 @@ msgstr "Den privata JWT-nyckeln bör vara minst {0} bytes lång." msgid "The configuration {0} is not correctly set." msgstr "Konfigurationen {0} är inte korrekt inställd." +msgid "The {0} directory is not writable." +msgstr "" + +msgid "The {0} directory should not be writable." +msgstr "" + +msgid "A valid JWT key pair was found." +msgstr "" + +msgid "A valid JWT key pair is missing." +msgstr "" + +msgid "Run the create JWT keys script to create a valid JWT secret and public key pair:" +msgstr "" + msgid "The refresh token should be a valid UUID." msgstr "Uppdateringstoken bör vara ett giltigt UUID." @@ -3034,28 +3571,52 @@ msgstr "" msgid "The client should be a valid IP or a valid domain." msgstr "" -msgid "Could not validate the smtp settings." +msgid "SMTP Settings coherent. You may send a test email to validate them." msgstr "" -msgid "Could not validate the smtp settings found in database." +msgid "SMTP Setting errors: {0}" msgstr "" -msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgid "The {0} plugin endpoints are disabled." msgstr "" -msgid "To fix this problem, you need to configure the SMTP server again." +msgid "The {0} plugin endpoints are enabled." +msgstr "" + +msgid "It is recommended to disable the plugin endpoints." +msgstr "" + +msgid "Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true." +msgstr "" + +msgid "Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}." msgstr "" msgid "not found" msgstr "" +msgid "The SMTP Settings source is: {0}." +msgstr "" + +msgid "It is recommended to set the SMTP Settings in the database through the administration section." +msgstr "" + msgid "database" msgstr "databas" msgid "env variables" msgstr "" -msgid "undefined" +msgid "Could not validate the smtp settings." +msgstr "" + +msgid "Could not validate the smtp settings found in database." +msgstr "" + +msgid "The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database." +msgstr "" + +msgid "To fix this problem, you need to configure the SMTP server again." msgstr "" msgid "Passbolt test email" @@ -3088,9 +3649,6 @@ msgstr "Systemkontroll" msgid "Subscription key" msgstr "Prenumerationsnyckel" -msgid "Database" -msgstr "Databas" - msgid "Server keys" msgstr "Servernycklar" @@ -3205,18 +3763,6 @@ msgstr "En tvingande ssl status krävs." msgid "The force ssl setting should be a valid boolean." msgstr "Den tvingande ssl inställningen bör vara en giltig boolean." -msgid "The database schema does not match the one expected" -msgstr "Databasschemat matchar inte det förväntade" - -msgid "The database cannot be installed" -msgstr "Databasen kunde inte installeras" - -msgid "There was a problem creating the first user" -msgstr "Ett problem uppstod när den första användaren skulle skapas" - -msgid "There was a problem creating the registration token" -msgstr "Det gick inte att skapa registreringstoken" - msgid "The passbolt config is writable." msgstr "Konfigurationen för passbolt är skrivbar." @@ -3226,8 +3772,14 @@ msgstr "Konfigurationen för passbolt är inte skrivbar." msgid "Ensure the file " msgstr "Se till att filen " -msgid "you can try:" -msgstr "du kan prova:" +msgid "The server OpenPGP private key file is writable." +msgstr "Serverns privata OpenPGP nyckel-fil är skrivbar." + +msgid "The server OpenPGP private key file is not writable." +msgstr "Serverns privata OpenPGP nyckel-fil är inte skrivbar." + +msgid "Ensure the file {0} is writable by the webserver user." +msgstr "Se till att filen {0} är skrivbar av webbserveranvändaren." msgid "The server OpenPGP public key file is writable." msgstr "Serverns publika OpenPGP nyckel-fil är skrivbar." @@ -3235,14 +3787,17 @@ msgstr "Serverns publika OpenPGP nyckel-fil är skrivbar." msgid "The server OpenPGP public key file is not writable." msgstr "Serverns publika OpenPGP nyckel-fil är inte skrivbar." -msgid "Ensure the file {0} is writable by the webserver user." -msgstr "Se till att filen {0} är skrivbar av webbserveranvändaren." +msgid "The database schema does not match the one expected" +msgstr "Databasschemat matchar inte det förväntade" -msgid "The server OpenPGP private key file is writable." -msgstr "Serverns privata OpenPGP nyckel-fil är skrivbar." +msgid "The database cannot be installed" +msgstr "Databasen kunde inte installeras" -msgid "The server OpenPGP private key file is not writable." -msgstr "Serverns privata OpenPGP nyckel-fil är inte skrivbar." +msgid "There was a problem creating the first user" +msgstr "Ett problem uppstod när den första användaren skulle skapas" + +msgid "There was a problem creating the registration token" +msgstr "Det gick inte att skapa registreringstoken" msgid "Create your user account!" msgstr "Skapa ditt användarkonto!" @@ -3442,18 +3997,9 @@ msgstr "URL-omskrivningen är inte korrekt konfigurerad på din server." msgid "GPG is configured correctly." msgstr "GPG är korrekt konfigurerad." -msgid "GPG Configuration" -msgstr "Konfiguration av GPG" - msgid "SSL" msgstr "SSL" -msgid "SSL access is enabled." -msgstr "SSL-åtkomst är aktiverad." - -msgid "SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue." -msgstr "SSL-åtkomst är inte aktiverad. Du kan fortfarande gå vidare men det rekommenderas starkt att du konfigurerar din webbserver för att använda HTTPS innan du fortsätter." - msgid "Start configuration" msgstr "Börja konfigurationen" @@ -3544,9 +4090,6 @@ msgstr "Hälsokontroller" msgid "Passbolt API Status" msgstr "Passbolt API Status" -msgid "SSL access is not enabled." -msgstr "SSL-åtkomst är inte aktiverad." - msgid "Group manager" msgstr "Gruppchef" diff --git a/src/Application.php b/src/Application.php index 5bffaba9e7..b2f3466c1a 100644 --- a/src/Application.php +++ b/src/Application.php @@ -37,6 +37,7 @@ use App\Service\Cookie\AbstractSecureCookieService; use App\Service\Cookie\DefaultSecureCookieService; use App\ServiceProvider\CommandServiceProvider; +use App\ServiceProvider\HealthcheckServiceProvider; use App\ServiceProvider\ResourceServiceProvider; use App\ServiceProvider\SetupServiceProvider; use App\ServiceProvider\TestEmailServiceProvider; @@ -297,6 +298,7 @@ public function services(ContainerInterface $container): void if (PHP_SAPI === 'cli') { $container->addServiceProvider(new CommandServiceProvider()); } + $container->addServiceProvider(new HealthcheckServiceProvider()); } /** diff --git a/src/Authenticator/GpgAuthenticator.php b/src/Authenticator/GpgAuthenticator.php index 827ccbd20d..7b1c1abc68 100644 --- a/src/Authenticator/GpgAuthenticator.php +++ b/src/Authenticator/GpgAuthenticator.php @@ -470,7 +470,7 @@ private function _normalizeRequestData(ServerRequest $request): ?array if (isset($data['data'])) { $data = $data['data']; } - if (isset($data['gpg_auth'])) { + if (isset($data['gpg_auth']) && is_array($data['gpg_auth'])) { $this->_data = $data['gpg_auth']; } else { $this->_data = null; diff --git a/src/Command/DropTablesCommand.php b/src/Command/DropTablesCommand.php index 3a9055a957..11f7ae72bc 100644 --- a/src/Command/DropTablesCommand.php +++ b/src/Command/DropTablesCommand.php @@ -45,7 +45,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $datasource = $args->getOption('datasource'); $connection = ConnectionManager::get($datasource); - $tables = ConnectionManager::get('default')->getSchemaCollection()->listTables(); + $tables = ConnectionManager::get($datasource)->getSchemaCollection()->listTables(); foreach ($tables as $table) { $io->out(__('Dropping table ' . $table)); $quotedTableName = $connection->getDriver()->quoteIdentifier($table); diff --git a/src/Command/HealthcheckCommand.php b/src/Command/HealthcheckCommand.php index 2a00178796..64a885da00 100644 --- a/src/Command/HealthcheckCommand.php +++ b/src/Command/HealthcheckCommand.php @@ -16,37 +16,23 @@ */ namespace App\Command; +use App\Service\Command\ProcessUserService; +use App\Service\Healthcheck\HealthcheckCliInterface; +use App\Service\Healthcheck\HealthcheckServiceCollector; +use App\Service\Healthcheck\HealthcheckServiceInterface; +use App\Service\Healthcheck\HealthcheckWithOptionsInterface; +use App\Service\Healthcheck\SkipHealthcheckInterface; use App\Utility\Application\FeaturePluginAwareTrait; -use App\Utility\Healthchecks; -use App\Utility\Healthchecks\CoreHealthchecks; -use App\Utility\Healthchecks\SslHealthchecks; +use Cake\Collection\Collection; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; -use Cake\Core\Configure; -use Cake\Http\Client; -use Passbolt\JwtAuthentication\Service\AccessToken\JwksGetService; -use Passbolt\JwtAuthentication\Service\AccessToken\JwtAbstractService; -use Passbolt\JwtAuthentication\Service\AccessToken\JwtKeyPairService; -use Passbolt\JwtAuthentication\Service\AccessToken\JwtTokenCreateService; class HealthcheckCommand extends PassboltCommand { use DatabaseAwareCommandTrait; use FeaturePluginAwareTrait; - public const ALL_HEALTH_CHECKS = [ - 'environment', - 'configFiles', - 'core', - 'ssl', - 'database', - 'gpg', - 'application', - 'jwt', - 'smtpSettings', - ]; - /** * Total number of errors for that check * @@ -77,15 +63,25 @@ class HealthcheckCommand extends PassboltCommand */ private $args; - private ?Client $client; + /** + * @var \App\Service\Command\ProcessUserService + */ + protected ProcessUserService $processUserService; + + private HealthcheckServiceCollector $healthcheckServiceCollector; /** - * @param ?\Cake\Http\Client $client client requesting the healthcheck status + * @param \App\Service\Command\ProcessUserService $processUserService Process user service + * @param \App\Service\Healthcheck\HealthcheckServiceCollector $healthcheckServiceCollector Health check service collector. */ - public function __construct(?Client $client) - { + public function __construct( + ProcessUserService $processUserService, + HealthcheckServiceCollector $healthcheckServiceCollector + ) { parent::__construct(); - $this->client = $client; + + $this->processUserService = $processUserService; + $this->healthcheckServiceCollector = $healthcheckServiceCollector; } /** @@ -118,43 +114,14 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar ]); // Checks - $parser - ->addOption('environment', [ - 'help' => __d('cake_console', 'Run environment tests only.'), - 'boolean' => true, - ]) - ->addOption('configFiles', [ - 'help' => __d('cake_console', 'Run configFiles tests only.'), - 'boolean' => true, - ]) - ->addOption('core', [ - 'help' => __d('cake_console', 'Run core tests only.'), - 'boolean' => true, - ]) - ->addOption('ssl', [ - 'help' => __d('cake_console', 'Run SSL tests only.'), - 'boolean' => true, - ]) - ->addOption('database', [ - 'help' => __d('cake_console', 'Run database tests only.'), - 'boolean' => true, - ]) - ->addOption('gpg', [ - 'help' => __d('cake_console', 'Run gpg tests only.'), - 'boolean' => true, - ]) - ->addOption('application', [ - 'help' => __d('cake_console', 'Run passbolt app tests only.'), - 'boolean' => true, - ]) - ->addOption('jwt', [ - 'help' => __d('cake_console', 'Run passbolt JWT tests only.'), - 'boolean' => true, - ]) - ->addOption('smtpSettings', [ - 'help' => __d('cake_console', 'Run SMTP Settings tests only.'), + $domains = $this->healthcheckServiceCollector->getDomainsInCollectedServices(); + foreach ($domains as $domain) { + $domainReadable = $this->healthcheckServiceCollector->getTitleFromDomain($domain); + $parser->addOption($domain, [ + 'help' => __d('cake_console', 'Run {0} tests only.', $domainReadable), 'boolean' => true, ]); + } $this->addDatasourceOption($parser); @@ -172,9 +139,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $this->args = $args; // Root user is not allowed to execute this command. - $this->assertCurrentProcessUser($io); - - $results = []; + $this->assertCurrentProcessUser($io, $this->processUserService); // display options $displayOptions = array_keys($this->_displayOptions); @@ -182,34 +147,52 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $this->_displayOptions[$option] = $args->getOption($option); } - // if user only want to run one check + // If user only want to run one check $paramChecks = []; - $checks = self::ALL_HEALTH_CHECKS; - foreach ($checks as $check) { - if ($args->getOption($check)) { - $paramChecks[] = $check; + $healthcheckServices = $this->healthcheckServiceCollector->getServices(); + foreach ($healthcheckServices as $healthcheckService) { + if ( + $healthcheckService instanceof HealthcheckCliInterface + && $args->getOption($healthcheckService->cliOption()) + ) { + $paramChecks[] = $healthcheckService; + } + + if ($healthcheckService instanceof HealthcheckWithOptionsInterface) { + $healthcheckService->setOptions($this->args->getOptions()); } } if (count($paramChecks)) { - $checks = $paramChecks; + $healthcheckServices = $paramChecks; } - // Run all the selected checks $io->out(' Healthcheck shell', 0); - foreach ($checks as $check) { + // Get services from collector and run checks + $resultCollection = new Collection([]); + foreach ($healthcheckServices as $healthcheckService) { $io->out('.', 0); // Print a dot for each checks to show progress - $results = array_merge(Healthchecks::{$check}(), $results); + $result = $healthcheckService->check(); + $resultCollection = $this->appendResult($resultCollection, $result); } + // Remove all dots - $io->out(str_repeat(chr(0x08), count($checks)) . str_repeat(' ', count($checks)), 0); + $io->out(str_repeat(chr(0x08), $resultCollection->count()) . str_repeat(' ', $resultCollection->count()), 0); - // Print results $io->out(); $io->hr(); - foreach ($checks as $check) { - $fn = 'assert' . ucfirst($check); - $this->{$fn}($results); + + // Print results + $resultsGroupByDomain = $resultCollection->groupBy(function ($result) { + return $result->domain(); + }); + foreach ($resultsGroupByDomain as $domain => $checkResults) { + $this->title($this->healthcheckServiceCollector->getTitleFromDomain($domain)); + + foreach ($checkResults as $checkResult) { + $this->render($checkResult); + } } + $io->out(); $this->summary(); @@ -217,662 +200,56 @@ public function execute(Arguments $args, ConsoleIo $io): ?int } /** - * Assert all the checks - * - * @param array $checks existing results - * @return void - */ - public function assertEnvironment($checks = null) - { - if (!isset($checks)) { - $checks = Healthchecks::environment(); - } - $this->title(__('Environment')); - $this->assert( - $checks['environment']['phpVersion'], - __('PHP version {0}.', PHP_VERSION), - __('PHP version is too low, passbolt need PHP {0} or higher.', Configure::read(Healthchecks::PHP_MIN_VERSION_CONFIG)) // phpcs:ignore - ); - $nextMinPhpVersion = Configure::read(Healthchecks::PHP_NEXT_MIN_VERSION_CONFIG); - $this->warning( - $checks['environment']['nextMinPhpVersion'], - __('PHP version is {0} or above.', $nextMinPhpVersion), - __( - 'PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment.', // phpcs:ignore - $nextMinPhpVersion - ) - ); - $this->assert( - $checks['environment']['pcre'], - __('PCRE compiled with unicode support.'), - __('PCRE has not been compiled with Unicode support.'), - __('Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring.') - ); - $this->assert( - $checks['environment']['tmpWritable'], - __('The temporary directory and its content are writable and not executable.'), - __('The temporary directory and its content are not writable, or are executable.'), - [ - __('Ensure the temporary directory and its content are writable by the webserver user.'), - __('you can try:'), - 'sudo chown -R ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . TMP, - 'sudo chmod -R 775 $(find ' . TMP . ' -type d)', - 'sudo chmod -R 664 $(find ' . TMP . ' -type f)', - ] - ); - $this->assert( - $checks['environment']['logWritable'], - __('The logs directory and its content are writable.'), - __('The logs directory and its content are not writable.'), - [ - __('Ensure the logs directory and its content are writable by the user the webserver user.'), - __('you can try:'), - 'sudo chown -R ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . ROOT . 'logs', - 'sudo chmod 775 $(find ' . ROOT . 'logs -type d)', - 'sudo chmod 664 $(find ' . ROOT . 'logs -type f)', - ] - ); - $this->assert( - $checks['environment']['image'], - __('GD or Imagick extension is installed.'), - __('You must enable the gd or imagick extensions to use Passbolt.'), - [ - __('See. https://secure.php.net/manual/en/book.image.php'), - __('See. https://secure.php.net/manual/en/book.imagick.php'), - ] - ); - $this->assert( - $checks['environment']['intl'], - __('Intl extension is installed.'), - __('You must enable the intl extension to use Passbolt.'), - [ - __('See. https://secure.php.net/manual/en/book.intl.php'), - ] - ); - $this->assert( - $checks['environment']['mbstring'], - __('Mbstring extension is installed.'), - __('You must enable the mbstring extension to use Passbolt.'), - [ - __('See. https://secure.php.net/manual/en/book.mbstring.php'), - ] - ); -// $this->assert( -// $checks['environment']['allow_url_fopen'], -// __('The allow_url_fopen setting is activated in php.ini.'), -// __('You must activate the allow_url_fopen setting in php.ini to use Passbolt.'), -// [ -// __('See. https://www.php.net/manual/en/filesystem.configuration.php'), -// ] -// ); - } - - /** - * Assert config files exist - * - * @param array $checks existing results - * @return void - */ - public function assertConfigFiles($checks = null) - { - if (!isset($checks)) { - $checks = Healthchecks::configFiles(); - } - $this->title(__('Config files')); - $this->assert( - $checks['configFile']['app'], - __('The application config file is present'), - __('The application config file is missing in {0}', CONFIG), - __('Copy {0} to {1}', CONFIG . 'app.default.php', CONFIG . 'app.php') - ); - $this->warning( - $checks['configFile']['passbolt'], - __('The passbolt config file is present'), - __('The passbolt config file is missing in {0}', CONFIG), - [ - __('Copy {0} to {1}', CONFIG . 'passbolt.default.php', CONFIG . 'passbolt.php'), - __('The passbolt config file is not required if passbolt is configured with environment variables'), - ] - ); - } - - /** - * Assert the core file configuration - * - * @param array $checks existing results - * @return void - */ - public function assertCore($checks = null) - { - if (!isset($checks)) { - $checks = (new CoreHealthchecks($this->client))->all($checks); - } - $this->title(__('Core config')); - $this->assert( - $checks['core']['debugDisabled'], - __('Debug mode is off.'), - __('Debug mode is on.'), - __('Set debug = false; in {0}', CONFIG . 'passbolt.php') - ); - $this->assert( - $checks['core']['cache'], - __('Cache is working.'), - __('Cache is NOT working.'), - __('Check the settings in {0}', CONFIG . 'app.php') - ); - $this->assert( - $checks['core']['salt'], - __('Unique value set for security.salt'), - __('Default value found for security.salt'), - __('Edit the security.salt in {0}', CONFIG . 'app.php') - ); - $this->assert( - $checks['core']['fullBaseUrl'], - __('Full base url is set to {0}', $checks['core']['info']['fullBaseUrl']), - __('Full base url is not set. The application is using: {0}.', $checks['core']['info']['fullBaseUrl']), - __('Edit App.fullBaseUrl in {0}', CONFIG . 'passbolt.php') - ); - $this->assert( - $checks['core']['validFullBaseUrl'], - __('App.fullBaseUrl validation OK.'), - __('App.fullBaseUrl does not validate. {0}.', $checks['core']['info']['fullBaseUrl']), - [ - __('Edit App.fullBaseUrl in {0}', CONFIG . 'passbolt.php'), - __('Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt'), - ] - ); - $this->assert( - $checks['core']['fullBaseUrlReachable'], - __('/healthcheck/status is reachable.'), - __('Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl'), - [ - __('Check that the domain name is correct in {0}', CONFIG . 'passbolt.php'), - __('Check the network settings'), - ] - ); - } - - /** - * Assert the core file configuration - * - * @param array $checks existing results - * @return void - */ - public function assertSSL($checks = null) - { - if (!isset($checks)) { - $checks = (new SslHealthchecks($this->client))->all($checks); - } - $this->title(__('SSL Certificate')); - $this->warning( - $checks['ssl']['peerValid'], - __('SSL peer certificate validates'), - __('SSL peer certificate does not validate') - ); - $this->warning( - $checks['ssl']['hostValid'], - __('Hostname is matching in SSL certificate.'), - __('Hostname does not match when validating certificates.') - ); - $this->warning( - $checks['ssl']['notSelfSigned'], - __('Not using a self-signed certificate'), - __('Using a self-signed certificate'), - [ - 'Check https://help.passbolt.com/faq/hosting/troubleshoot-ssl', - ] - ); - if (isset($checks['ssl']['info'])) { - $this->help($checks['ssl']['info']); - } - } - - /** - * Assert database is in order - * - * @param array $checks existing results - * @return void + * @param \Cake\Collection\Collection $resultCollection result collection + * @param \App\Service\Healthcheck\HealthcheckServiceInterface $result healthcheck + * @return \Cake\Collection\Collection */ - public function assertDatabase($checks = null) + private function appendResult(Collection $resultCollection, HealthcheckServiceInterface $result): Collection { - if (!isset($checks['database']) || !isset($checks['application'])) { - $datasource = $this->args->getOption('datasource'); - $checks = array_merge(Healthchecks::database($datasource), Healthchecks::application()); - } - $this->title(__('Database')); - $this->assert( - $checks['database']['connect'], - __('The application is able to connect to the database'), - __('The application is not able to connect to the database.'), - [ - __( - 'Double check the host, database name, username and password in {0}.', - CONFIG . 'passbolt.php' - ), - __('Make sure the database exists and is accessible for the given database user.'), - ] - ); - $this->assert( - $checks['database']['tablesCount'], - __('{0} tables found', $checks['database']['info']['tablesCount']), - __('No table found'), - [ - __('Run the install script to install the database tables'), - 'sudo su -s /bin/bash -c "' . ROOT . DS . 'bin/cake passbolt install" ' . PROCESS_USER, - ] - ); - $this->assert( - $checks['database']['defaultContent'], - __('Some default content is present'), - __('No default content found'), - [ - __('Run the install script to set the default content such as roles and permission types'), - 'sudo su -s /bin/bash -c "' . ROOT . DS . 'bin/cake passbolt install" ' . PROCESS_USER, - ] - ); - $this->assert( - $checks['application']['schema'], - __('The database schema up to date.'), - __('The database schema is not up to date.'), - [ - __('Run the migration scripts:'), - 'sudo su -s /bin/bash -c "' . ROOT . DS . 'bin/cake migrations migrate --no-lock" ' . PROCESS_USER, - __('See. https://www.passbolt.com/help/tech/update'), - ] - ); - } + $skipResult = $result instanceof SkipHealthcheckInterface && $result->isSkipped(); - /** - * Assert passbolt application configuration is in order - * - * @param array $checks existing results - * @return void - */ - public function assertApplication($checks = null) - { - if (!isset($checks)) { - $checks = Healthchecks::application(); - } - $this->title(__('Application configuration')); - if (!isset($checks['application']['latestVersion'])) { - $this->assert( - false, - __('Could connect to passbolt repository to check versions.'), - __('Could not connect to passbolt repository to check versions') . ' ' . - __('It is not possible check if your version is up to date.'), - __('Check the network configuration to allow this script to check for updates.') - ); - } else { - $this->assert( - $checks['application']['latestVersion'], - __('Using latest passbolt version ({0}).', Configure::read('passbolt.version')), - __( - 'This installation is not up to date. Currently using {0} and it should be {1}.', - Configure::read('passbolt.version'), - $checks['application']['info']['remoteVersion'] - ), - __('See. https://www.passbolt.com/help/tech/update') - ); + if (!$skipResult) { + /** @var \Cake\Collection\Collection $resultCollection */ + $resultCollection = $resultCollection->appendItem($result); } - $this->assert( - $checks['application']['sslForce'], - __('Passbolt is configured to force SSL use.'), - __('Passbolt is not configured to force SSL use.'), - __('Set passbolt.ssl.force to true in {0}.', CONFIG . 'passbolt.php') - ); - $this->assert( - $checks['application']['sslFullBaseUrl'], - __('App.fullBaseUrl is set to HTTPS.'), - __('App.fullBaseUrl is not set to HTTPS.'), - __('Check App.fullBaseUrl url scheme in {0}.', CONFIG . 'passbolt.php') - ); - $this->assert( - $checks['application']['seleniumDisabled'], - __('Selenium API endpoints are disabled.'), - __('Selenium API endpoints are active. This setting should be used for testing only.'), - __('Set passbolt.selenium.active to false in {0}.', CONFIG . 'passbolt.php') - ); - $this->warning( - $checks['application']['robotsIndexDisabled'], - __('Search engine robots are told not to index content.'), - __('Search engine robots are not told not to index content.'), - __('Set passbolt.meta.robots to false in {0}.', CONFIG . 'passbolt.php') - ); - $selfRegistrationPluginName = 'Self Registration'; - $selfRegistrationChecks = $checks['application']['registrationClosed']; - $this->notice( - $selfRegistrationChecks['isSelfRegistrationPluginEnabled'], - __('The {0} plugin is enabled.', $selfRegistrationPluginName), - __('The {0} plugin is disabled.', $selfRegistrationPluginName), - __('Enable the plugin in order to define self registration settings.') - ); - $this->notice( - is_null($selfRegistrationChecks['selfRegistrationProvider']), - __('Registration is closed, only administrators can add users.'), - __('The self registration provider is: {0}.', $selfRegistrationChecks['selfRegistrationProvider']) - ); - $this->warning( - $selfRegistrationChecks['isRegistrationPublicRemovedFromPassbolt'], - __('The deprecated self registration public setting was not found in {0}.', CONFIG . 'passbolt.php'), - __('The deprecated self registration public setting was found in {0}.', CONFIG . 'passbolt.php'), - __('You may remove the "passbolt.registration.public" setting.') - ); - $this->warning( - $checks['application']['hostAvailabilityCheckEnabled'], - __('Host availability will be checked.'), - __('Host availability checking is disabled.'), - [ - __('Make sure this instance is not publicly available on the internet.'), - __('Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true.'), - __('Or set passbolt.email.validate.mx to true in {0}.', CONFIG . 'passbolt.php'), - ] - ); - $this->warning( - $checks['application']['jsProd'], - __('Serving the compiled version of the javascript app.'), - __('Using non-compiled Javascript. Passbolt will be slower.'), - __('Set passbolt.js.build to production in {0}', CONFIG . 'passbolt.php') - ); - $this->warning( - $checks['application']['emailNotificationEnabled'], - __('All email notifications will be sent.'), - __('Some email notifications are disabled by the administrator.') - ); - } - /** - * Warn GPG environment is in order - * - * @param array $checks existing results - * @return void - */ - public function assertGpgEnv($checks = null) - { - $this->assert( - $checks['gpg']['lib'], - __('PHP GPG Module is installed and loaded.'), - __('PHP GPG Module is not installed or loaded.'), - __('Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php') . - __('Make sure to add extension=gnupg.so in php ini files for both php-cli and php.') - ); - $this->assert( - $checks['gpg']['gpgHome'], - __('The environment variable GNUPGHOME is set to {0}.', $checks['gpg']['info']['gpgHome']), - __('The environment variable GNUPGHOME is set to {0}, but the directory does not exist.', $checks['gpg']['info']['gpgHome']),// phpcs:ignore - [ - __('Ensure the keyring location exists and is accessible by the webserver user.'), - __('you can try:'), - 'sudo mkdir -p ' . $checks['gpg']['info']['gpgHome'], - 'sudo chown -R ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . $checks['gpg']['info']['gpgHome'], - 'sudo chmod 700 ' . $checks['gpg']['info']['gpgHome'], - __('You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}.', CONFIG . 'passbolt.php'),// phpcs:ignore - ] - ); - if ($checks['gpg']['gpgHome']) { - $this->assert( - $checks['gpg']['gpgHomeWritable'], - __('The directory {0} containing the keyring is writable by the webserver user.', $checks['gpg']['info']['gpgHome']),// phpcs:ignore - __('The directory {0} containing the keyring is not writable by the webserver user.', $checks['gpg']['info']['gpgHome']),// phpcs:ignore - [ - __('Ensure the keyring location is accessible by the webserver user.'), - __('you can try:'), - 'sudo chown -R ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . $checks['gpg']['info']['gpgHome'], - 'sudo chmod 700 ' . $checks['gpg']['info']['gpgHome'], - ] - ); - } + return $resultCollection; } /** - * Warn GPG settings are in order + * Print result of given health check. * - * @param array $checks existing results + * @param \App\Service\Healthcheck\HealthcheckServiceInterface $healthcheckService Health check service. * @return void */ - public function assertGpg($checks = null) + public function render(HealthcheckServiceInterface $healthcheckService): void { - if (!isset($checks)) { - $checks = Healthchecks::gpg(); - } - $this->title(__('GPG Configuration')); - $this->assertGpgEnv($checks); - if ($checks['gpg']['gpgKey']) { - $this->assert( - $checks['gpg']['gpgKeyNotDefault'], - __('The server OpenPGP key is not the default one'), - __('Do not use the default OpenPGP key for the server'), - [ - __('Create a key, export it and add the fingerprint to {0}', CONFIG . 'passbolt.php'), - __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), - ] - ); - } else { - $this->assert( - $checks['gpg']['gpgKey'], - __('The server OpenPGP key is set'), - __('The server OpenPGP key is not set'), - [ - __('Create a key, export it and add the fingerprint to {0}', CONFIG . 'passbolt.php'), - __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), - ] - ); - } - $this->assert( - $checks['gpg']['gpgKeyPublic'] && $checks['gpg']['gpgKeyPublicReadable'] && $checks['gpg']['gpgKeyPublicBlock'],// phpcs:ignore - __('The public key file is defined in {0} and readable.', CONFIG . 'passbolt.php'), - __('The public key file is not defined in {0} or not readable.', CONFIG . 'passbolt.php'), - [ - __('Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}.', CONFIG . 'passbolt.php'),// phpcs:ignore - __('Ensure there is a public key armored block in the key file.'), - __('Ensure the public key defined in {0} exists and is accessible by the webserver user.', CONFIG . 'passbolt.php'),// phpcs:ignore - __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), - ] - ); - $this->assert( - $checks['gpg']['gpgKeyPrivate'] && $checks['gpg']['gpgKeyPrivateReadable'] && $checks['gpg']['gpgKeyPrivateBlock'],// phpcs:ignore - __('The private key file is defined in {0} and readable.', CONFIG . 'passbolt.php'), - __('The private key file is not defined in {0} or not readable.', CONFIG . 'passbolt.php'), - [ - __('Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}.', CONFIG . 'passbolt.php'),// phpcs:ignore - __('Ensure there is a private key armored block in the key file.'), - __('Ensure the private key defined in {0} exists and is accessible by the webserver user.', CONFIG . 'passbolt.php'),// phpcs:ignore - __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), - ] - ); - $this->assert( - $checks['gpg']['gpgKeyPrivateFingerprint'] && $checks['gpg']['gpgKeyPublicFingerprint'], - __('The server key fingerprint matches the one defined in {0}.', CONFIG . 'passbolt.php'), - __('The server key fingerprint doesn\'t match the one defined in {0}.', CONFIG . 'passbolt.php'), - [ - __('Double check the key fingerprint, example: '), - 'sudo su -s /bin/bash -c "gpg --list-keys --fingerprint --home ' . $checks['gpg']['info']['gpgHome'] . '" ' . PROCESS_USER . ' | grep -i -B 2 \'SERVER_KEY_EMAIL\'',// phpcs:ignore - __('SERVER_KEY_EMAIL: The email you used when you generated the server key.'), - __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), - ] - ); - $this->assert( - $checks['gpg']['gpgKeyPublicInKeyring'], - __('The server public key defined in the {0} (or environment variables) is in the keyring.', CONFIG . 'passbolt.php'),// phpcs:ignore - __('The server public key defined in the {0} (or environment variables) is not in the keyring', CONFIG . 'passbolt.php'),// phpcs:ignore - [ - __('Import the private server key in the keyring of the webserver user.'), - __('you can try:'), - 'sudo su -s /bin/bash -c "gpg --home ' . $checks['gpg']['info']['gpgHome'] . ' --import ' . $checks['gpg']['info']['gpgKeyPrivate'] . '" ' . PROCESS_USER,// phpcs:ignore - ] - ); - $this->assert( - $checks['gpg']['gpgKeyPublicEmail'], - __('There is a valid email id defined for the server key.'), - __('The server key does not have a valid email id.'), - __('Edit or generate another key with a valid email id.') - ); - - if ($checks['gpg']['gpgKeyPublicInKeyring']) { - $tip = [ - __('Make sure that the server private key is valid and that there is no passphrase.'), - __('Make sure you imported the private server key in the keyring of the webserver user.'), - __('you can try:'), - 'sudo su -s /bin/bash -c "gpg --home ' . $checks['gpg']['info']['gpgHome'] . ' --import ' . $checks['gpg']['info']['gpgKeyPrivate'] . '" ' . PROCESS_USER, // phpcs:ignore - ]; - - $this->assert( - $checks['gpg']['canEncrypt'], - __('The public key can be used to encrypt a message.'), - __('The public key cannot be used to encrypt a message'), - $tip - ); - $this->assert( - $checks['gpg']['canSign'], - __('The private key can be used to sign a message.'), - __('The private key cannot be used to sign a message'), - $tip - ); - $this->assert( - $checks['gpg']['canEncryptSign'], - __('The public and private keys can be used to encrypt and sign a message.'), - __('The public and private keys cannot be used to encrypt and sign a message') - ); - $this->assert( - $checks['gpg']['canDecrypt'], - __('The private key can be used to decrypt a message.'), - __('The private key cannot be used to decrypt a message') - ); - $this->assert( - $checks['gpg']['canDecryptVerify'], - __('The private key can be used to decrypt and verify a message.'), - __('The private key cannot be used to decrypt and verify a message') - ); - $this->assert( - $checks['gpg']['canVerify'], - __('The public key can be used to verify a signature.'), - __('The public key cannot be used to verify a signature.') - ); - $gopengpgHelpMessage = ['Remove all empty new lines above the end block line.']; - $this->assert( - $checks['gpg']['isPublicServerKeyGopengpgCompatible'], - 'The server public key format is Gopengpg compatible.', - 'The server public key format is not Gopengpg compatible.', - $gopengpgHelpMessage - ); - $this->assert( - $checks['gpg']['isPrivateServerKeyGopengpgCompatible'], - 'The server private key format is Gopengpg compatible.', - 'The server public key format is not Gopengpg compatible.', - $gopengpgHelpMessage - ); - } - } - - /** - * Assert that JWT files exist, are writable and valid - * - * @param array $checks existing results - * @return void - */ - public function assertJWT($checks = null) - { - $jwtKeyPairService = new JwtKeyPairService(); - if (!isset($checks)) { - $checks = Healthchecks::jwt($jwtKeyPairService); - } - - $this->title(__('JWT Authentication')); - - $this->warning( - $checks['jwt']['isEnabled'], - __('The {0} plugin is enabled', 'JWT Authentication'), - __('The {0} plugin is disabled', 'JWT Authentication'), - __('Set the environment variable {0} to true', 'PASSBOLT_PLUGINS_JWT_AUTHENTICATION_ENABLED'), - ); - - if (!$this->isFeaturePluginEnabled('JwtAuthentication')) { - return; - } - - $directory = JwtAbstractService::JWT_CONFIG_DIR; - $this->assert( - $checks['jwt']['jwtWritable'], - "The {$directory} directory is not writable.", - "The {$directory} directory should not be writable.", - [ - 'You can try: ', - 'sudo chown -Rf root:' . PROCESS_USER . ' ' . $directory, - 'sudo chmod 750 ' . $directory, - 'sudo chmod 640 ' . JwtTokenCreateService::JWT_SECRET_KEY_PATH, - 'sudo chmod 640 ' . JwksGetService::PUBLIC_KEY_PATH, - ] - ); - - $fixCmd = $jwtKeyPairService->getCreateJwtKeysCommand(); - $this->assert( - $checks['jwt']['keyPairValid'], - __('A valid JWT key pair was found'), - __('A valid JWT key pair is missing'), - [ - __('Run the create JWT keys script to create a valid JWT secret and public key pair:'), - 'sudo su -s /bin/bash -c "' . $fixCmd . '" ' . PROCESS_USER, - ] - ); - } - - /** - * Assert that SMTP settings are defined in DB and valid - * - * @param array|null $checks existing results - * @return void - */ - public function assertSmtpSettings(?array $checks = null): void - { - if (!isset($checks)) { - $checks = Healthchecks::smtpSettings(); - } - - $smtpSettingsCheck = $checks['smtpSettings']; - $isPluginEnabled = $smtpSettingsCheck['isEnabled']; - $pluginName = 'SMTP Settings'; - - $this->title($pluginName); - $this->warning( - $isPluginEnabled, - __('The {0} plugin is enabled.', $pluginName), - __('The {0} plugin is disabled.', $pluginName) . ' ' . - __('Enable the plugin in order to define SMTP settings in the database.') - ); - - if (!$isPluginEnabled) { - return; + switch ($healthcheckService->level()) { + case 'error': + $this->assert( + $healthcheckService->isPassed(), + $healthcheckService->getSuccessMessage(), + $healthcheckService->getFailureMessage(), + $healthcheckService->getHelpMessage() + ); + break; + case 'warning': + $this->warning( + $healthcheckService->isPassed(), + $healthcheckService->getSuccessMessage(), + $healthcheckService->getFailureMessage(), + $healthcheckService->getHelpMessage() + ); + break; + case 'notice': + $this->notice( + $healthcheckService->isPassed(), + $healthcheckService->getSuccessMessage(), + $healthcheckService->getFailureMessage(), + $healthcheckService->getHelpMessage() + ); + break; } - - $source = $smtpSettingsCheck['source']; - $isInDb = $smtpSettingsCheck['isInDb']; - - $validationErrors = $smtpSettingsCheck['errorMessage'] ?? null; - $isSmtpSettingsValid = !is_string($validationErrors); - $this->assert( - $isSmtpSettingsValid, - __('SMTP Settings coherent. You may send a test email to validate them.'), - __('SMTP Setting errors: {0}', $validationErrors) - ); - - $msg = __('The SMTP Settings source is: {0}.', $source); - $this->warning( - $isInDb, - $msg, - $msg, - __('It is recommended to set the SMTP Settings in the database through the administration section.') - ); - - $arePluginEndpointsDisabled = $smtpSettingsCheck['areEndpointsDisabled']; - $this->warning( - $arePluginEndpointsDisabled, - __('The {0} plugin endpoints are disabled.', $pluginName), - __('The {0} plugin endpoints are enabled.', $pluginName), - [ - __('It is recommended to disable the plugin endpoints.'), - __('Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true.'), - __('Or set passbolt.security.smtpSettings.endpointsDisabled to true in {0}.', CONFIG . 'passbolt.php'), - ] - ); } /** diff --git a/src/Command/InstallCommand.php b/src/Command/InstallCommand.php index 1f746b376b..2ae9d7fe51 100644 --- a/src/Command/InstallCommand.php +++ b/src/Command/InstallCommand.php @@ -17,17 +17,28 @@ namespace App\Command; use App\Model\Entity\Role; +use App\Service\Command\ProcessUserService; +use App\Service\Healthcheck\ConfigFiles\AppConfigFileHealthcheck; +use App\Service\Healthcheck\Core\ValidFullBaseUrlCoreHealthcheck; +use App\Service\Healthcheck\Database\ConnectDatabaseHealthcheck; +use App\Service\Healthcheck\Database\TablesCountDatabaseHealthcheck; +use App\Service\Healthcheck\Gpg\FingerprintMatchGpgHealthcheck; +use App\Service\Healthcheck\Gpg\HomeVariableDefinedGpgHealthcheck; +use App\Service\Healthcheck\Gpg\HomeVariableWritableGpgHealthcheck; +use App\Service\Healthcheck\Gpg\KeyNotDefaultGpgHealthcheck; +use App\Service\Healthcheck\Gpg\PrivateKeyReadableAndParsableGpgHealthcheck; +use App\Service\Healthcheck\Gpg\PublicKeyEmailGpgHealthcheck; +use App\Service\Healthcheck\Gpg\PublicKeyReadableAndParsableGpgHealthcheck; +use App\Service\Healthcheck\HealthcheckServiceCollector; +use App\Service\Healthcheck\HealthcheckWithOptionsInterface; use App\Utility\Application\FeaturePluginAwareTrait; -use App\Utility\Healthchecks; -use App\Utility\Healthchecks\CoreHealthchecks; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; use Cake\Core\Configure; use Cake\Core\Exception\CakeException; -use Cake\Http\Client; use Passbolt\JwtAuthentication\Error\Exception\AccessToken\InvalidJwtKeyPairException; -use Passbolt\JwtAuthentication\Service\AccessToken\JwtAbstractService; +use Passbolt\JwtAuthentication\JwtAuthenticationPlugin; use Passbolt\JwtAuthentication\Service\AccessToken\JwtKeyPairService; use PassboltTestData\Command\InsertCommand; @@ -36,17 +47,27 @@ class InstallCommand extends PassboltCommand use DatabaseAwareCommandTrait; use FeaturePluginAwareTrait; - private ?Client $client; + private HealthcheckServiceCollector $healthcheckServiceCollector; + + /** + * @var \App\Service\Command\ProcessUserService + */ + protected ProcessUserService $processUserService; /** * The client passed in the constructor might be null when run using the selenium tests * - * @param ?\Cake\Http\Client $client client requesting the healthcheck status + * @param \App\Service\Command\ProcessUserService $processUserService Process user service. + * @param \App\Service\Healthcheck\HealthcheckServiceCollector $healthcheckServiceCollector Health check service collector. */ - public function __construct(?Client $client = null) - { + public function __construct( + ProcessUserService $processUserService, + HealthcheckServiceCollector $healthcheckServiceCollector + ) { parent::__construct(); - $this->client = $client; + + $this->processUserService = $processUserService; + $this->healthcheckServiceCollector = $healthcheckServiceCollector; } /** @@ -110,7 +131,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int // Root user is not allowed to execute this command. // This command needs to be executed with the same user as the webserver. - $this->assertCurrentProcessUser($io); + $this->assertCurrentProcessUser($io, $this->processUserService); // Create a JWT key pair if ($this->isFeaturePluginEnabled('JwtAuthentication')) { @@ -127,7 +148,6 @@ public function execute(Arguments $args, ConsoleIo $io): ?int if ($args->getOption('quick')) { return $this->quickInstall($args, $io); } - // Normal mode if (!$this->healthchecks($args, $io)) { return $this->errorCode(); @@ -185,8 +205,9 @@ protected function userRegistration(Arguments $args, ConsoleIo $io): bool '--last-name', $args->getOption('admin-last-name'), ]; + $registerUserCommand = new RegisterUserCommand($this->processUserService); $result = $this->executeCommand( - RegisterUserCommand::class, + $registerUserCommand, $this->formatOptions($args, $options), $io ); @@ -314,7 +335,41 @@ protected function keyringInit(Arguments $args, ConsoleIo $io): ?int $io->out(__('Import the server private key in the keyring')); $io->hr(); - return $this->executeCommand(KeyringInitCommand::class, $this->formatOptions($args), $io); + $keyringInitCommand = new KeyringInitCommand($this->processUserService); + + return $this->executeCommand($keyringInitCommand, $this->formatOptions($args), $io); + } + + /** + * @return \App\Service\Healthcheck\HealthcheckServiceInterface[] + */ + protected function getInstallCheckHealthcheckServices(): array + { + $domainsIncluded = []; + if ($this->isFeaturePluginEnabled(JwtAuthenticationPlugin::class)) { + $domainsIncluded = [ + HealthcheckServiceCollector::DOMAIN_JWT, + ]; + } + + $servicesIncluded = [ + AppConfigFileHealthcheck::class, + ValidFullBaseUrlCoreHealthcheck::class, + PublicKeyReadableAndParsableGpgHealthcheck::class, + PrivateKeyReadableAndParsableGpgHealthcheck::class, + HomeVariableDefinedGpgHealthcheck::class, + HomeVariableWritableGpgHealthcheck::class, + FingerprintMatchGpgHealthcheck::class, + PublicKeyEmailGpgHealthcheck::class, + ]; + + // In production don't accept default GPG server key + if (!Configure::read('debug')) { + $servicesIncluded[] = KeyNotDefaultGpgHealthcheck::class; + } + $servicesIncluded[] = ConnectDatabaseHealthcheck::class; + + return $this->healthcheckServiceCollector->getServicesFiltered($domainsIncluded, $servicesIncluded); } /** @@ -328,61 +383,17 @@ protected function healthchecks(Arguments $args, ConsoleIo $io): bool { $io->nl(); $io->out(__('Running baseline checks, please wait...')); + $healthcheckServices = $this->getInstallCheckHealthcheckServices(); try { - // Make sure the baseline config files are present - $checks = Healthchecks::configFiles(); - if (!$checks['configFile']['app']) { - throw new CakeException(__('The application config file is missing in {0}.', CONFIG)); - } - - // Check application url config - $checks = (new CoreHealthchecks($this->client))->all($checks); - if (!$checks['core']['fullBaseUrl'] && !$checks['core']['validFullBaseUrl']) { - $msg = __('The fullBaseUrl is not set or not valid. {0}', $checks['core']['info']['fullBaseUrl']); - throw new CakeException($msg); - } - - // Check that a GPG configuration id is provided - $checks = Healthchecks::gpg(); - if (!$checks['gpg']['gpgKey'] || !$checks['gpg']['gpgKeyPublic'] || !$checks['gpg']['gpgKeyPrivate']) { - throw new CakeException(__('The GnuPG config for the server is not available or incomplete')); - } - // Check if keyring is present and writable - if (!$checks['gpg']['gpgHome']) { - throw new CakeException(__('The OpenPGP keyring location is not set.')); - } - if (!$checks['gpg']['gpgHomeWritable']) { - throw new CakeException(__('The OpenPGP keyring location is not writable.')); - } - - // In production don't accept default GPG server key - if (!Configure::read('debug')) { - if (!$checks['gpg']['gpgKeyNotDefault']) { - $msg = __('Default GnuPG server key cannot be used in production.'); - $msg .= ' ' . __('Please change the values of passbolt.gpg.server in config/passbolt.php.'); - $msg .= ' ' . __('If you do not have yet a server key, please generate one.'); - $msg .= ' ' . __('Take a look at the install documentation for more information.'); - throw new CakeException($msg); + foreach ($healthcheckServices as $healthcheckService) { + if ($healthcheckService instanceof HealthcheckWithOptionsInterface) { + $healthcheckService->setOptions($args->getOptions()); } - } - - // Check that there is a public and private key found at the given path - if (!$checks['gpg']['gpgKeyPublicReadable']) { - $msg = 'No public key found at the given path {0}'; - throw new CakeException(__($msg, Configure::read('GPG.serverKey.public'))); - } - if (!$checks['gpg']['gpgKeyPrivateReadable']) { - $msg = 'No private key found at the given path {0}'; - throw new CakeException(__($msg, Configure::read('GPG.serverKey.private'))); - } - // Check that the public and private key match the fingerprint - if (!$checks['gpg']['gpgKeyPrivateFingerprint'] || !$checks['gpg']['gpgKeyPublicFingerprint']) { - $msg = __('The server key fingerprint does not match the fingerprint mentioned in config/passbolt.php'); - throw new CakeException($msg); - } - if (!$checks['gpg']['gpgKeyPublicEmail']) { - throw new CakeException(__('The server public key should have an email id.')); + $healthcheckService->check(); + if (!$healthcheckService->isPassed()) { + throw new CakeException($healthcheckService->getFailureMessage()); + } } } catch (CakeException $e) { $this->error($e->getMessage(), $io); @@ -391,16 +402,13 @@ protected function healthchecks(Arguments $args, ConsoleIo $io): bool return false; } - // Database checks - $checks = Healthchecks::database($args->getOption('datasource')); - if (!$checks['database']['connect'] || !$checks['database']['supportedBackend']) { - $this->error(__('There are some issues with the database configuration.'), $io); - $this->error(__('Please run ./bin/cake passbolt healthcheck for more information and help.'), $io); - - return false; - } - if ($checks['database']['tablesCount']) { - if (!$args->getOption('force')) { + // If force is false, and database is populated, warn + if (!$args->getOption('force')) { + /** @var \App\Service\Healthcheck\Database\TablesCountDatabaseHealthcheck $tableCountCheck */ + $tableCountCheck = $this->healthcheckServiceCollector + ->getService(TablesCountDatabaseHealthcheck::class); + $tableCountCheck->check(); + if ($tableCountCheck->isPassed()) { $msg = __('Some tables are already present in the database.') . ' '; $msg .= __('A new installation would override existing data.'); $this->error($msg, $io); @@ -410,29 +418,6 @@ protected function healthchecks(Arguments $args, ConsoleIo $io): bool } } - // JWT checks - if ($this->isFeaturePluginEnabled('JwtAuthentication')) { - $jwtKeyPairService = new JwtKeyPairService(); - $checks = Healthchecks::jwt($jwtKeyPairService); - if ($checks['jwt']['keyPairValid'] !== true) { - $fixCmd = $jwtKeyPairService->getCreateJwtKeysCommand(); - - $this->error('The JWT key pair is not valid, or cannot be found.', $io); - $this->error('Please run ' . $fixCmd . ' to create a valid pair.', $io); - - return false; - } - - if ($checks['jwt']['jwtWritable'] !== true) { - $folder = JwtAbstractService::JWT_CONFIG_DIR; - $fixCmd = "sudo chmod 775 $(find $folder -type d)"; - $this->error("The directory {$folder} is not writable.", $io); - $this->error('You can try ' . $fixCmd, $io); - - return false; - } - } - $this->success(__('Critical healthchecks are OK'), $io); return true; diff --git a/src/Command/KeyringInitCommand.php b/src/Command/KeyringInitCommand.php index 759a6cb7f8..cb61a2d5a8 100644 --- a/src/Command/KeyringInitCommand.php +++ b/src/Command/KeyringInitCommand.php @@ -16,6 +16,7 @@ */ namespace App\Command; +use App\Service\Command\ProcessUserService; use App\Utility\OpenPGP\OpenPGPBackendFactory; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; @@ -25,6 +26,21 @@ class KeyringInitCommand extends PassboltCommand { + /** + * @var \App\Service\Command\ProcessUserService + */ + protected ProcessUserService $processUserService; + + /** + * @param \App\Service\Command\ProcessUserService $processUserService Process user service. + */ + public function __construct(ProcessUserService $processUserService) + { + parent::__construct(); + + $this->processUserService = $processUserService; + } + /** * @inheritDoc */ @@ -43,7 +59,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int parent::execute($args, $io); // Root user is not allowed to execute this command. - $this->assertCurrentProcessUser($io); + $this->assertCurrentProcessUser($io, $this->processUserService); try { $filePath = Configure::read('passbolt.gpg.serverKey.private'); diff --git a/src/Command/MigrateCommand.php b/src/Command/MigrateCommand.php index 630d74ebee..6955f9a0ae 100644 --- a/src/Command/MigrateCommand.php +++ b/src/Command/MigrateCommand.php @@ -16,6 +16,7 @@ */ namespace App\Command; +use App\Service\Command\ProcessUserService; use Cake\Command\CacheClearallCommand; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; @@ -28,6 +29,21 @@ class MigrateCommand extends PassboltCommand { use DatabaseAwareCommandTrait; + /** + * @var \App\Service\Command\ProcessUserService + */ + protected ProcessUserService $processUserService; + + /** + * @param \App\Service\Command\ProcessUserService $processUserService Process user service. + */ + public function __construct(ProcessUserService $processUserService) + { + parent::__construct(); + + $this->processUserService = $processUserService; + } + /** * @inheritDoc */ @@ -60,7 +76,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int // Root user is not allowed to execute this command. // This command needs to be executed with the same user as the webserver. - $this->assertCurrentProcessUser($io); + $this->assertCurrentProcessUser($io, $this->processUserService); // Backup if ($this->backup($args, $io)) { diff --git a/src/Command/MigratePostgresCommand.php b/src/Command/MigratePostgresCommand.php index 574201628c..3db5d78497 100644 --- a/src/Command/MigratePostgresCommand.php +++ b/src/Command/MigratePostgresCommand.php @@ -16,6 +16,7 @@ */ namespace App\Command; +use App\Service\Command\ProcessUserService; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; @@ -33,6 +34,21 @@ class MigratePostgresCommand extends PassboltCommand 'V350ConvertIdFieldsToUuidFields', ]; + /** + * @var \App\Service\Command\ProcessUserService + */ + protected ProcessUserService $processUserService; + + /** + * @param \App\Service\Command\ProcessUserService $processUserService Process user service. + */ + public function __construct(ProcessUserService $processUserService) + { + parent::__construct(); + + $this->processUserService = $processUserService; + } + /** * @inheritDoc */ @@ -54,7 +70,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int // Root user is not allowed to execute this command. // This command needs to be executed with the same user as the webserver. - $this->assertCurrentProcessUser($io); + $this->assertCurrentProcessUser($io, $this->processUserService); /** @var \Cake\Database\Connection $connection */ $connection = ConnectionManager::get($args->getOption('datasource')); diff --git a/src/Command/PassboltCommand.php b/src/Command/PassboltCommand.php index 11e391ebd4..0fc89a92ed 100644 --- a/src/Command/PassboltCommand.php +++ b/src/Command/PassboltCommand.php @@ -16,6 +16,7 @@ */ namespace App\Command; +use App\Service\Command\ProcessUserService; use Cake\Command\Command; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; @@ -27,11 +28,6 @@ */ class PassboltCommand extends Command { - /** - * @var bool|null - */ - public static $isUserRoot = null; - /** * The Passbolt welcome banner should be shown only once. * This is a memory cell to that aim. @@ -60,10 +56,6 @@ public function initialize(): void parent::initialize(); CommandBootstrap::init(); - - if (self::$isUserRoot === null) { - self::$isUserRoot = (PROCESS_USER === 'root'); - } } /** @@ -239,16 +231,18 @@ protected function success(string $msg, ConsoleIo $io): void * Checks if user running the command is valid or not. If not, aborts or shows warning depending on severity. * * @param \Cake\Console\ConsoleIo $io IO object. + * @param \App\Service\Command\ProcessUserService $processUserService process user service * @return void */ - protected function assertCurrentProcessUser(ConsoleIo $io) + protected function assertCurrentProcessUser(ConsoleIo $io, ProcessUserService $processUserService) { - if (!$this->assertNotRoot($io)) { + if (!$this->assertNotRoot($processUserService, $io)) { $this->error(__('aborting'), $io); $this->abort(); } - if (!$this->isWebserverUser()) { + $isWebserverUser = in_array($processUserService->getName(), self::KNOWN_WEBSERVER_USERS); + if (!$isWebserverUser) { $io->out(); $io->warning(__('Passbolt commands should only be executed as the web server user.')); $io->out(); @@ -268,12 +262,13 @@ protected function assertCurrentProcessUser(ConsoleIo $io) * Some of the passbolt commands shouldn't be executed as root. * By instance it's the case of the healthcheck command that needs to be executed with the same user as your web server. * + * @param \App\Service\Command\ProcessUserService $processUserService Process user service. * @param \Cake\Console\ConsoleIo $io Console IO. * @return bool true if user is root */ - protected function assertNotRoot(ConsoleIo $io): bool + protected function assertNotRoot(ProcessUserService $processUserService, ConsoleIo $io): bool { - if (self::$isUserRoot) { + if ($processUserService->getName() === 'root') { $io->out(); $this->error('Passbolt commands cannot be executed as root.', $io); $io->out(); diff --git a/src/Command/RecoverUserCommand.php b/src/Command/RecoverUserCommand.php index 482f99366e..f8095200b3 100644 --- a/src/Command/RecoverUserCommand.php +++ b/src/Command/RecoverUserCommand.php @@ -19,6 +19,7 @@ use App\Error\Exception\ValidationException; use App\Model\Entity\AuthenticationToken; use App\Model\Entity\User; +use App\Service\Command\ProcessUserService; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; @@ -29,6 +30,21 @@ */ class RecoverUserCommand extends PassboltCommand { + /** + * @var \App\Service\Command\ProcessUserService + */ + protected ProcessUserService $processUserService; + + /** + * @param \App\Service\Command\ProcessUserService $processUserService Process user service. + */ + public function __construct(ProcessUserService $processUserService) + { + parent::__construct(); + + $this->processUserService = $processUserService; + } + /** * @inheritDoc */ @@ -56,8 +72,9 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar public function execute(Arguments $args, ConsoleIo $io): ?int { parent::execute($args, $io); + // Root user is not allowed to execute this command. - $this->assertCurrentProcessUser($io); + $this->assertCurrentProcessUser($io, $this->processUserService); $username = $args->getOption('username'); diff --git a/src/Command/RegisterUserCommand.php b/src/Command/RegisterUserCommand.php index 256bb272ae..b85cc17f75 100644 --- a/src/Command/RegisterUserCommand.php +++ b/src/Command/RegisterUserCommand.php @@ -19,6 +19,7 @@ use App\Error\Exception\ValidationException; use App\Model\Entity\Role; use App\Model\Entity\User; +use App\Service\Command\ProcessUserService; use App\Utility\UserAccessControl; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; @@ -52,6 +53,21 @@ class RegisterUserCommand extends PassboltCommand */ protected $AuthenticationTokens; + /** + * @var \App\Service\Command\ProcessUserService + */ + protected ProcessUserService $processUserService; + + /** + * @param \App\Service\Command\ProcessUserService $processUserService Process user service. + */ + public function __construct(ProcessUserService $processUserService) + { + parent::__construct(); + + $this->processUserService = $processUserService; + } + /** * Initializes the Shell * acts as constructor for subclasses @@ -112,7 +128,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int parent::execute($args, $io); // Root user is not allowed to execute this command. - $this->assertCurrentProcessUser($io); + $this->assertCurrentProcessUser($io, $this->processUserService); // Who is creating the user? // use the oldest admin or temporary non existing one diff --git a/src/Controller/Groups/GroupsDeleteController.php b/src/Controller/Groups/GroupsDeleteController.php index a710c09985..9eca55624f 100644 --- a/src/Controller/Groups/GroupsDeleteController.php +++ b/src/Controller/Groups/GroupsDeleteController.php @@ -239,6 +239,7 @@ protected function _transferContentOwners(Group $group): void if (Configure::read('passbolt.plugins.folders.enabled')) { $foldersIdsBlockingDelete = $this->Permissions ->findSharedAcosByAroIsSoleOwner(PermissionsTable::FOLDER_ACO, $group->id) + ->all() ->extract('aco_foreign_key') ->toArray(); $contentIdBlockingDelete = array_merge($contentIdBlockingDelete, $foldersIdsBlockingDelete); diff --git a/src/Controller/Healthcheck/HealthcheckIndexController.php b/src/Controller/Healthcheck/HealthcheckIndexController.php index 6f21eff4d4..6aacdc78e5 100644 --- a/src/Controller/Healthcheck/HealthcheckIndexController.php +++ b/src/Controller/Healthcheck/HealthcheckIndexController.php @@ -17,12 +17,25 @@ namespace App\Controller\Healthcheck; use App\Controller\AppController; -use App\Model\Entity\Role; -use App\Utility\Healthchecks; +use App\Service\Healthcheck\Application\LatestVersionApplicationHealthcheck; +use App\Service\Healthcheck\Application\SelfRegistrationProviderApplicationHealthcheck; +use App\Service\Healthcheck\Core\FullBaseUrlCoreHealthcheck; +use App\Service\Healthcheck\Database\ConnectDatabaseHealthcheck; +use App\Service\Healthcheck\Database\TablesCountDatabaseHealthcheck; +use App\Service\Healthcheck\Environment\PhpVersionHealthcheck; +use App\Service\Healthcheck\Gpg\FingerprintMatchGpgHealthcheck; +use App\Service\Healthcheck\HealthcheckServiceCollector; +use App\Service\Healthcheck\Ssl\HostValidSslHealthcheck; +use App\Service\Healthcheck\Ssl\IsRequestHttpsSslHealthcheck; +use App\Service\Healthcheck\Ssl\PeerValidSslHealthcheck; +use Cake\Collection\Collection; +use Cake\Collection\CollectionInterface; use Cake\Core\Configure; use Cake\Event\EventInterface; -use Cake\Http\Client; use Cake\Http\Exception\ForbiddenException; +use Cake\Utility\Hash; +use Passbolt\SmtpSettings\Service\Healthcheck\SettingsValidationSmtpSettingsHealthcheck; +use Passbolt\SmtpSettings\Service\Healthcheck\SmtpSettingsSettingsSourceHealthcheck; class HealthcheckIndexController extends AppController { @@ -46,53 +59,157 @@ public function beforeFilter(EventInterface $event) * Display information about the passbolt instance * It is only available in debug mode and for logged in administrators * - * @param ?\Cake\Http\Client $client client used to query the healthcheck endpoint + * @param \App\Service\Healthcheck\HealthcheckServiceCollector $healthcheckServiceCollector Health check service collector. + * @param \App\Service\Healthcheck\Ssl\IsRequestHttpsSslHealthcheck $isRequestHttpsSslHealthcheck SSL enabled health check. * @return void + * @throws \Cake\Http\Exception\ForbiddenException if the requesting user is not an admin */ - public function index(?Client $client) - { - // Allow access only in debug mode or if logged in as admin - if (Configure::read('debug') == 0) { - if ($this->User->role() != Role::ADMIN) { - throw new ForbiddenException(); + public function index( + HealthcheckServiceCollector $healthcheckServiceCollector, + IsRequestHttpsSslHealthcheck $isRequestHttpsSslHealthcheck + ) { + $this->User->assertIsAdmin(); + + $ignoreDomains = $this->getDomainsIgnore(); + $healthcheckServices = []; + foreach ($healthcheckServiceCollector->getServices() as $healthcheckService) { + if (in_array($healthcheckService->domain(), $ignoreDomains)) { + continue; } + + $healthcheckServices[] = $healthcheckService; } + $healthcheckServices[] = $isRequestHttpsSslHealthcheck; - $checks = Healthchecks::all($client); - $checks = array_merge($this->__webChecks(), $checks); + $resultCollection = new Collection([]); + foreach ($healthcheckServices as $healthcheckService) { + $result = $healthcheckService->check(); + + $resultCollection = $resultCollection->appendItem($result); + } + + $resultsGroupByDomain = $resultCollection->groupBy(function ($result) { + return $result->domain(); + }); if (!$this->request->is('json')) { + $body = []; + foreach ($resultsGroupByDomain as $domain => $checkResults) { + $key = $healthcheckServiceCollector->getTitleFromDomain($domain); + $body[$key] = $checkResults; + } $this->viewBuilder() ->setLayout('login') ->setTemplatePath('Healthcheck') ->setTemplate('index'); - $this->success(__('All checks ran successfully!'), $checks); + $this->success(__('All checks ran successfully!'), $body); } else { - $this->success(__('The operation was successful.'), $checks); + $healthcheckResult = $this->formatCollectionResponseAsPerLegacy($resultsGroupByDomain); + + $this->success(__('The operation was successful.'), $healthcheckResult); } } /** - * Check that need/can to be performed in web context only - * - * @access private - * @return array + * @return void + * @throws \Cake\Http\Exception\ForbiddenException if the endpoint is deactivated */ - private function __webChecks(): array + private function throwErrorIsEndpointIsDisabled(): void { - $checks['ssl']['is'] = $this->request->is('https'); + if (!Configure::read(self::PASSBOLT_PLUGINS_HEALTHCHECK_SECURITY_INDEX_ENDPOINT_ENABLED)) { + throw new ForbiddenException(__('Healthcheck security index endpoint disabled.')); + } + } - return $checks; + /** + * @return array + */ + private function getDomainsIgnore(): array + { + return [HealthcheckServiceCollector::DOMAIN_JWT]; } /** - * @return void - * @throws \Cake\Http\Exception\ForbiddenException if the endpoint is deactivated + * Formats given collection as per legacy array structure. This helps us keep backward compatibility. + * + * @deprecated As of v4.7.0, this is just to keep backward compatibility. + * @param \Cake\Collection\CollectionInterface $resultsGroupByDomain Result collection to format as per legacy array format. + * @return array */ - private function throwErrorIsEndpointIsDisabled(): void + private function formatCollectionResponseAsPerLegacy(CollectionInterface $resultsGroupByDomain): array { - if (!Configure::read(self::PASSBOLT_PLUGINS_HEALTHCHECK_SECURITY_INDEX_ENDPOINT_ENABLED)) { - throw new ForbiddenException(__('Healthcheck security index endpoint disabled.')); + $result = []; + + /** @var \App\Service\Healthcheck\HealthcheckServiceInterface[] $checkResults */ + foreach ($resultsGroupByDomain as $domainKey => $checkResults) { + if ($domainKey === HealthcheckServiceCollector::DOMAIN_CONFIG_FILES) { + $domainKey = 'configFile'; + } + $result[$domainKey] = []; + foreach ($checkResults as $checkResult) { + $value = $checkResult->isPassed(); + + /** + * **Note:** + * These are conditions that is required to be backward compatible. + * This is @deprecated way (appending keys into result array) and should not be done anywhere else. + */ + if ($checkResult instanceof LatestVersionApplicationHealthcheck) { + // Application domain additional fields + if ($checkResult->isExceptionThrown()) { + $value = null; + } + + $result[$domainKey]['configPath'] = CONFIG . 'passbolt.php'; + + $result[$domainKey]['info']['remoteVersion'] = $checkResult->getRemoteVersion(); + $result[$domainKey]['info']['currentVersion'] = Configure::read('passbolt.version'); + } elseif ($checkResult instanceof FullBaseUrlCoreHealthcheck) { + // Core domain additional fields + $result[$domainKey]['info']['fullBaseUrl'] = Configure::read('App.fullBaseUrl'); + } elseif ($checkResult instanceof ConnectDatabaseHealthcheck) { + // Database domain additional fields + $result[$domainKey]['supportedBackend'] = $value; + } elseif ($checkResult instanceof TablesCountDatabaseHealthcheck) { + // Database domain info fields + $result[$domainKey]['info']['tablesCount'] = $checkResult->getTableCount(); + } elseif ($checkResult instanceof PhpVersionHealthcheck) { + // Environment domain additional fields + $result[$domainKey]['gnupg'] = extension_loaded('gnupg'); + $result[$domainKey]['info']['phpVersion'] = PHP_VERSION; + } elseif ($checkResult instanceof SmtpSettingsSettingsSourceHealthcheck) { + // SMTP settings additional fields + $result[$domainKey]['source'] = $checkResult->getSource(); + } elseif ($checkResult instanceof SettingsValidationSmtpSettingsHealthcheck) { + $value = false; + if ($checkResult->getValidationError() !== '') { + $value = $checkResult->getValidationError(); + } + } elseif ($checkResult instanceof SelfRegistrationProviderApplicationHealthcheck) { + $value = $checkResult->getProvider(); + } elseif ($checkResult instanceof FingerprintMatchGpgHealthcheck) { + // GPG additional fields + $result[$domainKey]['gpgKeyPublicReadable'] = $checkResult->gpgKeyPublicReadable(); + $result[$domainKey]['gpgKeyPrivateReadable'] = $checkResult->gpgKeyPrivateReadable(); + $result[$domainKey]['gpgKeyPrivateFingerprint'] = $checkResult->isPrivateKeyInfoOK(); + $result[$domainKey]['gpgKeyPublic'] = (Configure::read('passbolt.gpg.serverKey.public') !== null); + $result[$domainKey]['gpgKeyPrivate'] = (Configure::read('passbolt.gpg.serverKey.private') !== null); + $result[$domainKey]['gpgKey'] = (Configure::read('passbolt.gpg.serverKey.fingerprint') !== null); + $result[$domainKey]['info']['gpgKeyPrivate'] = Configure::read('passbolt.gpg.serverKey.private'); + $result[$domainKey]['info']['gpgHome'] = $checkResult->gpgHome(); + } elseif ($checkResult instanceof IsRequestHttpsSslHealthcheck) { + // We don't want to set this in JSON response + continue; + } elseif ($checkResult instanceof HostValidSslHealthcheck || $checkResult instanceof PeerValidSslHealthcheck) { // phpcs:ignore + if (!empty($checkResult->getHelpMessage())) { + $result[$domainKey]['info'] = $checkResult->getHelpMessage()[0]; + } + } + + $result[$domainKey] = Hash::insert($result[$domainKey], $checkResult->getLegacyArrayKey(), $value); + } } + + return $result; } } diff --git a/src/Controller/Setup/RecoverStartController.php b/src/Controller/Setup/RecoverStartController.php index c6c399fb32..91a11d73cb 100644 --- a/src/Controller/Setup/RecoverStartController.php +++ b/src/Controller/Setup/RecoverStartController.php @@ -67,7 +67,6 @@ public function start(AbstractRecoverStartService $infoService, string $userId, $this->success(__('The operation was successful.'), $data); } else { $this->set('title', Configure::read('passbolt.meta.description')); - $infoService->setTemplate($this->viewBuilder()); } } } diff --git a/src/Controller/Setup/SetupStartController.php b/src/Controller/Setup/SetupStartController.php index 8150a9f52d..32df2fd8fe 100644 --- a/src/Controller/Setup/SetupStartController.php +++ b/src/Controller/Setup/SetupStartController.php @@ -60,11 +60,6 @@ public function start(AbstractSetupStartService $infoService, string $userId, st $this->success(__('The operation was successful.'), $data); } else { $this->set('title', Configure::read('passbolt.meta.description')); - - $this->viewBuilder() - ->setTemplatePath('/Setup') - ->setLayout('default') - ->setTemplate('start'); } } } diff --git a/src/Notification/Email/EmailSender.php b/src/Notification/Email/EmailSender.php index c3ac055281..aa34b57284 100644 --- a/src/Notification/Email/EmailSender.php +++ b/src/Notification/Email/EmailSender.php @@ -117,12 +117,16 @@ public function purifySubject(string $subject): string } /** + * Set the full base URL at the body level for the email content + * and at the higher level for the layout + * * @param \App\Notification\Email\Email $email Email to send * @return \App\Notification\Email\Email */ private function addFullBaseUrlToEmail(Email $email): Email { return $email->withData(array_merge_recursive($email->getData(), [ + 'fullBaseUrl' => $this->appFullBaseUrl, 'body' => [ 'fullBaseUrl' => $this->appFullBaseUrl, ], diff --git a/src/Service/Command/ProcessUserService.php b/src/Service/Command/ProcessUserService.php new file mode 100644 index 0000000000..73ded537f3 --- /dev/null +++ b/src/Service/Command/ProcessUserService.php @@ -0,0 +1,31 @@ +groupGetService->getNotDeletedOrFail($groupId); $this->assertChanges($group, $changes); - + $entitiesChangesDto = new EntitiesChangesDto(); $this->groupsTable->getConnection()->transactional( - function () use ($uac, $group, $metaData, $changes, $secrets) { + function () use ($uac, $group, $metaData, $changes, $secrets, $entitiesChangesDto) { $this->updateMetaData($uac, $group, $metaData); - $entitiesChangesDto = $this->addGroupsUsers($uac, $group, $changes, $secrets); + $entitiesChangesDto->pushUpdatedEntity($group); + $entitiesChangesDto->merge($this->addGroupsUsers($uac, $group, $changes, $secrets)); $entitiesChangesDto->merge($this->updateGroupsUsers($uac, $group, $changes)); $entitiesChangesDto->merge($this->deleteGroupsUsers($uac, $group, $changes)); $this->resourcesExpireResourcesService->expireResourcesForSecrets( @@ -139,7 +140,7 @@ function () use ($uac, $group, $metaData, $changes, $secrets) { } ); - return $group; + return $entitiesChangesDto; } /** diff --git a/src/Service/Healthcheck/Application/EmailNotificationEnabledApplicationHealthcheck.php b/src/Service/Healthcheck/Application/EmailNotificationEnabledApplicationHealthcheck.php new file mode 100644 index 0000000000..376ee20963 --- /dev/null +++ b/src/Service/Healthcheck/Application/EmailNotificationEnabledApplicationHealthcheck.php @@ -0,0 +1,110 @@ +status = !(preg_match('/false/', $sendEmailJson) === 1); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('All email notifications will be sent.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Some email notifications are disabled by the administrator.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return null; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'emailNotificationEnabled'; + } +} diff --git a/src/Service/Healthcheck/Application/HostAvailabilityCheckEnabledApplicationHealthcheck.php b/src/Service/Healthcheck/Application/HostAvailabilityCheckEnabledApplicationHealthcheck.php new file mode 100644 index 0000000000..9147c797a6 --- /dev/null +++ b/src/Service/Healthcheck/Application/HostAvailabilityCheckEnabledApplicationHealthcheck.php @@ -0,0 +1,114 @@ +status = Configure::read(EmailValidationRule::MX_CHECK_KEY); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Host availability will be checked.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Host availability checking is disabled.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Make sure this instance is not publicly available on the internet.'), + __('Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true.'), + __('Or set passbolt.email.validate.mx to true in {0}.', CONFIG . 'passbolt.php'), + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'hostAvailabilityCheckEnabled'; + } +} diff --git a/src/Service/Healthcheck/Application/JsProdApplicationHealthcheck.php b/src/Service/Healthcheck/Application/JsProdApplicationHealthcheck.php new file mode 100644 index 0000000000..b9d079b7bb --- /dev/null +++ b/src/Service/Healthcheck/Application/JsProdApplicationHealthcheck.php @@ -0,0 +1,110 @@ +status = (Configure::read('passbolt.js.build') === 'production'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Serving the compiled version of the javascript app.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Using non-compiled Javascript. Passbolt will be slower.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Set passbolt.js.build to production in {0}', CONFIG . 'passbolt.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'jsProd'; + } +} diff --git a/src/Service/Healthcheck/Application/LatestVersionApplicationHealthcheck.php b/src/Service/Healthcheck/Application/LatestVersionApplicationHealthcheck.php new file mode 100644 index 0000000000..3e18ff4849 --- /dev/null +++ b/src/Service/Healthcheck/Application/LatestVersionApplicationHealthcheck.php @@ -0,0 +1,208 @@ +remoteVersion = $this->getLatestTagName(); + $this->status = $this->isLatestVersion(); + } catch (\Exception $e) { + $this->exceptionThrown = true; + $this->remoteVersion = __('undefined'); + $this->status = false; + } + + return $this; + } + + /** + * Return true if the current installed version match the latest official one + * + * @return bool true if installed version is the latest + */ + private function isLatestVersion(): bool + { + $remoteVersion = ltrim($this->remoteVersion, 'v'); + $localVersion = ltrim(Configure::read('passbolt.version'), 'v'); + + return version_compare($localVersion, $remoteVersion, '>='); + } + + /** + * Return the current master version according to the official passbolt repository + * + * @throws \Exception if the github repository is not reachable + * @throws \Exception if the tag information cannot be retrieved + * @return string tag name such as 'v1.0.1' + */ + private function getLatestTagName(): string + { + $remoteTagName = Configure::read('passbolt.remote.version'); + if (is_null($remoteTagName)) { + $url = 'https://api.github.com/repos/passbolt/passbolt_api/releases/latest'; + try { + $HttpSocket = new Client(); + $results = $HttpSocket->get($url); + } catch (\Exception $e) { + throw new \Exception(__('Could not connect to github repository')); + } + $tags = json_decode($results->getStringBody(), true); + if (!isset($tags['tag_name'])) { + throw new \Exception(__('Could not read tag information on github repository')); + } + $remoteTagName = ltrim($tags['tag_name'], 'v'); + Configure::write('passbolt.remote.version', $remoteTagName); + } + + return $remoteTagName; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + $msg = __('Using latest passbolt version ({0}).', Configure::read('passbolt.version')); + if ($this->exceptionThrown) { + $msg = __('Could connect to passbolt repository to check versions.'); + } + + return $msg; + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + $msg = __( + 'This installation is not up to date. Currently using {0} and it should be {1}.', + Configure::read('passbolt.version'), + $this->remoteVersion + ); + if ($this->exceptionThrown) { + $msg = __('Could not connect to passbolt repository to check versions'); + $msg .= ' '; + $msg .= __('It is not possible check if your version is up to date.'); + } + + return $msg; + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + $msg = __('See https://www.passbolt.com/help/tech/update'); + if ($this->exceptionThrown) { + $msg = __('Check the network configuration to allow this script to check for updates.'); + } + + return $msg; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @return bool + */ + public function isExceptionThrown(): bool + { + return $this->exceptionThrown; + } + + /** + * @return string + */ + public function getRemoteVersion(): string + { + return $this->remoteVersion; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'latestVersion'; + } +} diff --git a/src/Service/Healthcheck/Application/RobotsIndexDisabledApplicationHealthcheck.php b/src/Service/Healthcheck/Application/RobotsIndexDisabledApplicationHealthcheck.php new file mode 100644 index 0000000000..c8235511e1 --- /dev/null +++ b/src/Service/Healthcheck/Application/RobotsIndexDisabledApplicationHealthcheck.php @@ -0,0 +1,110 @@ +status = ($robots !== false); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Search engine robots are told not to index content.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Search engine robots are not told not to index content.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Set passbolt.meta.robots to false in {0}.', CONFIG . 'passbolt.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'robotsIndexDisabled'; + } +} diff --git a/src/Service/Healthcheck/Application/SeleniumDisabledApplicationHealthcheck.php b/src/Service/Healthcheck/Application/SeleniumDisabledApplicationHealthcheck.php new file mode 100644 index 0000000000..3dc24aeef2 --- /dev/null +++ b/src/Service/Healthcheck/Application/SeleniumDisabledApplicationHealthcheck.php @@ -0,0 +1,109 @@ +status = !Configure::read('passbolt.selenium.active'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Selenium API endpoints are disabled.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Selenium API endpoints are active. This setting should be used for testing only.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Set passbolt.selenium.active to false in {0}.', CONFIG . 'passbolt.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'seleniumDisabled'; + } +} diff --git a/src/Service/Healthcheck/Application/SelfRegistrationPluginEnabledApplicationHealthcheck.php b/src/Service/Healthcheck/Application/SelfRegistrationPluginEnabledApplicationHealthcheck.php new file mode 100644 index 0000000000..4f059a51fd --- /dev/null +++ b/src/Service/Healthcheck/Application/SelfRegistrationPluginEnabledApplicationHealthcheck.php @@ -0,0 +1,123 @@ +selfRegistrationHealthcheckService = $selfRegistrationHealthcheckService; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + $selfRegistrationHealthcheck = $this->selfRegistrationHealthcheckService->getHealthcheck(); + $this->status = $selfRegistrationHealthcheck['isSelfRegistrationPluginEnabled']; + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_NOTICE; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The Self Registration plugin is enabled.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The Self Registration plugin is disabled.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Enable the plugin in order to define self registration settings.'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'registrationClosed.isSelfRegistrationPluginEnabled'; + } +} diff --git a/src/Service/Healthcheck/Application/SelfRegistrationProviderApplicationHealthcheck.php b/src/Service/Healthcheck/Application/SelfRegistrationProviderApplicationHealthcheck.php new file mode 100644 index 0000000000..db127b31a8 --- /dev/null +++ b/src/Service/Healthcheck/Application/SelfRegistrationProviderApplicationHealthcheck.php @@ -0,0 +1,137 @@ +selfRegistrationHealthcheckService = $selfRegistrationHealthcheckService; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + $selfRegistrationChecks = $this->selfRegistrationHealthcheckService->getHealthcheck(); + $this->status = is_null($selfRegistrationChecks['selfRegistrationProvider']); + $this->selfRegistrationProvider = $selfRegistrationChecks['selfRegistrationProvider']; + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_NOTICE; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Registration is closed, only administrators can add users.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The self registration provider is: {0}.', $this->selfRegistrationProvider); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return null; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'registrationClosed.selfRegistrationProvider'; + } + + /** + * @return string|null + */ + public function getProvider(): ?string + { + return $this->selfRegistrationProvider; + } +} diff --git a/src/Service/Healthcheck/Application/SelfRegistrationPublicRemovedApplicationHealthcheck.php b/src/Service/Healthcheck/Application/SelfRegistrationPublicRemovedApplicationHealthcheck.php new file mode 100644 index 0000000000..742b22add7 --- /dev/null +++ b/src/Service/Healthcheck/Application/SelfRegistrationPublicRemovedApplicationHealthcheck.php @@ -0,0 +1,123 @@ +selfRegistrationHealthcheckService = $selfRegistrationHealthcheckService; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + $selfRegistrationChecks = $this->selfRegistrationHealthcheckService->getHealthcheck(); + $this->status = $selfRegistrationChecks['isRegistrationPublicRemovedFromPassbolt']; + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The deprecated self registration public setting was not found in {0}.', CONFIG . 'passbolt.php'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The deprecated self registration public setting was found in {0}.', CONFIG . 'passbolt.php'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('You may remove the "passbolt.registration.public" setting.'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'registrationClosed.isRegistrationPublicRemovedFromPassbolt'; + } +} diff --git a/src/Service/Healthcheck/Application/SslForceApplicationHealthcheck.php b/src/Service/Healthcheck/Application/SslForceApplicationHealthcheck.php new file mode 100644 index 0000000000..4a00b07566 --- /dev/null +++ b/src/Service/Healthcheck/Application/SslForceApplicationHealthcheck.php @@ -0,0 +1,109 @@ +status = Configure::read('passbolt.ssl.force'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Passbolt is configured to force SSL use.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Passbolt is not configured to force SSL use.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Set passbolt.ssl.force to true in {0}.', CONFIG . 'passbolt.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'sslForce'; + } +} diff --git a/src/Service/Healthcheck/Application/SslFullBaseUrlApplicationHealthcheck.php b/src/Service/Healthcheck/Application/SslFullBaseUrlApplicationHealthcheck.php new file mode 100644 index 0000000000..bce11cbd58 --- /dev/null +++ b/src/Service/Healthcheck/Application/SslFullBaseUrlApplicationHealthcheck.php @@ -0,0 +1,110 @@ +status = ($https !== false); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('App.fullBaseUrl is set to HTTPS.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('App.fullBaseUrl is not set to HTTPS.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Check App.fullBaseUrl url scheme in {0}.', CONFIG . 'passbolt.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'sslFullBaseUrl'; + } +} diff --git a/src/Service/Healthcheck/ConfigFiles/AppConfigFileHealthcheck.php b/src/Service/Healthcheck/ConfigFiles/AppConfigFileHealthcheck.php new file mode 100644 index 0000000000..6eca2749dc --- /dev/null +++ b/src/Service/Healthcheck/ConfigFiles/AppConfigFileHealthcheck.php @@ -0,0 +1,108 @@ +status = (file_exists(CONFIG . 'app.php')); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_CONFIG_FILES; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return 'error'; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The application config file is present'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The application config file is missing in {0}', CONFIG); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Copy {0} to {1}', CONFIG . 'app.default.php', CONFIG . 'app.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_CONFIG_FILES; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'app'; + } +} diff --git a/src/Service/Healthcheck/ConfigFiles/PassboltConfigFileHealthcheck.php b/src/Service/Healthcheck/ConfigFiles/PassboltConfigFileHealthcheck.php new file mode 100644 index 0000000000..84cd67b7fd --- /dev/null +++ b/src/Service/Healthcheck/ConfigFiles/PassboltConfigFileHealthcheck.php @@ -0,0 +1,111 @@ +status = (file_exists(CONFIG . 'passbolt.php')); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_CONFIG_FILES; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return 'warning'; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The passbolt config file is present'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The passbolt config file is missing in {0}', CONFIG); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Copy {0} to {1}', CONFIG . 'passbolt.default.php', CONFIG . 'passbolt.php'), + __('The passbolt config file is not required if passbolt is configured with environment variables'), + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_CONFIG_FILES; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'passbolt'; + } +} diff --git a/src/Service/Healthcheck/Core/CacheCoreHealthcheck.php b/src/Service/Healthcheck/Core/CacheCoreHealthcheck.php new file mode 100644 index 0000000000..20842d660e --- /dev/null +++ b/src/Service/Healthcheck/Core/CacheCoreHealthcheck.php @@ -0,0 +1,109 @@ +status = !empty(Cache::getConfig('_cake_core_')); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Cache is working.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Cache is NOT working.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Check the settings in {0}', CONFIG . 'app.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'cache'; + } +} diff --git a/src/Service/Healthcheck/Core/DebugDisabledCoreHealthcheck.php b/src/Service/Healthcheck/Core/DebugDisabledCoreHealthcheck.php new file mode 100644 index 0000000000..becd575423 --- /dev/null +++ b/src/Service/Healthcheck/Core/DebugDisabledCoreHealthcheck.php @@ -0,0 +1,109 @@ +status = (Configure::read('debug') === false); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Debug mode is off.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Debug mode is on.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Set debug to false in {0}', CONFIG . 'passbolt.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'debugDisabled'; + } +} diff --git a/src/Service/Healthcheck/Core/FullBaseUrlCoreHealthcheck.php b/src/Service/Healthcheck/Core/FullBaseUrlCoreHealthcheck.php new file mode 100644 index 0000000000..5a24e009d7 --- /dev/null +++ b/src/Service/Healthcheck/Core/FullBaseUrlCoreHealthcheck.php @@ -0,0 +1,112 @@ +status = (Configure::read('App.fullBaseUrl') !== null); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Full base url is set to {0}', Configure::read('App.fullBaseUrl')); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __( + 'Full base url is not set. The application is using: {0}.', + Configure::read('App.fullBaseUrl') + ); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Edit App.fullBaseUrl in {0}', CONFIG . 'passbolt.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'fullBaseUrl'; + } +} diff --git a/src/Service/Healthcheck/Core/FullBaseUrlReachableCoreHealthcheck.php b/src/Service/Healthcheck/Core/FullBaseUrlReachableCoreHealthcheck.php new file mode 100644 index 0000000000..3ed2e014e0 --- /dev/null +++ b/src/Service/Healthcheck/Core/FullBaseUrlReachableCoreHealthcheck.php @@ -0,0 +1,164 @@ +client = $client; + } + + /** + * In case the full base URL was found as unreachable, the + * result is cached in this variable, to be accessible by other services + * and to avoid unnecessary redundant curls. + * + * @return bool + */ + public function isHealthcheckEndpointUnreachable(): bool + { + return $this->isHealthcheckEndpointUnreachable; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if ($this->isHealthcheckEndpointUnreachable()) { + return $this; + } + + try { + $url = Router::url('/healthcheck/status.json', true); + + $options = [ + 'ssl_verify_peer' => false, + 'ssl_verify_peer_name' => false, + 'ssl_verify_host' => false, + ]; + $response = $this->client->get($url, [], $options)->getJson(); + if (isset($response['body'])) { + $this->status = ($response['body'] === 'OK'); + } + } catch (\Throwable $e) { + // Nothing to do here + } finally { + if ($this->status !== true) { + $this->isHealthcheckEndpointUnreachable = true; + } + } + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('/healthcheck/status is reachable.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Could not reach the /healthcheck/status with the url specified in App.fullBaseUrl'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Check that the domain name is correct in {0}', CONFIG . 'passbolt.php'), + __('Check the network settings'), + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'fullBaseUrlReachable'; + } +} diff --git a/src/Service/Healthcheck/Core/SaltCoreHealthcheck.php b/src/Service/Healthcheck/Core/SaltCoreHealthcheck.php new file mode 100644 index 0000000000..6a1f2bb268 --- /dev/null +++ b/src/Service/Healthcheck/Core/SaltCoreHealthcheck.php @@ -0,0 +1,109 @@ +status = (Configure::read('Security.salt') !== '__SALT__'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Unique value set for security.salt'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Default value found for security.salt'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Edit the security.salt in {0}', CONFIG . 'app.php'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'salt'; + } +} diff --git a/src/Service/Healthcheck/Core/ValidFullBaseUrlCoreHealthcheck.php b/src/Service/Healthcheck/Core/ValidFullBaseUrlCoreHealthcheck.php new file mode 100644 index 0000000000..b36a88edd2 --- /dev/null +++ b/src/Service/Healthcheck/Core/ValidFullBaseUrlCoreHealthcheck.php @@ -0,0 +1,113 @@ +status = Validation::url(Configure::read('App.fullBaseUrl'), true); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('App.fullBaseUrl validation OK.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('App.fullBaseUrl does not validate. {0}.', Configure::read('App.fullBaseUrl')); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Edit App.fullBaseUrl in {0}', CONFIG . 'passbolt.php'), + __('Select a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt'), + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_CORE; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'validFullBaseUrl'; + } +} diff --git a/src/Service/Healthcheck/Database/AbstractDatabaseHealthcheck.php b/src/Service/Healthcheck/Database/AbstractDatabaseHealthcheck.php new file mode 100644 index 0000000000..08f104c4d7 --- /dev/null +++ b/src/Service/Healthcheck/Database/AbstractDatabaseHealthcheck.php @@ -0,0 +1,96 @@ +getOptions()['datasource'] ?? 'default'; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_DATABASE; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_DATABASE; + } + + /** + * @inheritDoc + */ + public function setOptions(array $options): void + { + $this->additionalOptions = $options; + } + + /** + * @inheritDoc + */ + public function getOptions(): array + { + return $this->additionalOptions; + } +} diff --git a/src/Service/Healthcheck/Database/ConnectDatabaseHealthcheck.php b/src/Service/Healthcheck/Database/ConnectDatabaseHealthcheck.php new file mode 100644 index 0000000000..f9ef2045ef --- /dev/null +++ b/src/Service/Healthcheck/Database/ConnectDatabaseHealthcheck.php @@ -0,0 +1,119 @@ +getDatasource(); + try { + /** @var \Cake\Database\Connection $connection */ + $connection = ConnectionManager::get($datasource); + $this->isDriverSupported = $this->isDriverSupported(); + if (!$this->isDriverSupported) { + return $this; + } + $connection->getDriver()->connect(); + $this->status = true; + } catch (MissingConnectionException $connectionError) { + // Do nothing + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The application is able to connect to the database'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + if (!$this->isDriverSupported) { + return __('The driver defined in the database configuration is not supported.'); + } + + return __('The application is not able to connect to the database.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __( + 'Ensure that the driver defined in {0} is one of the following: {1}.', + CONFIG . 'passbolt.php', + implode(', ', self::SUPPORTED_DRIVERS) + ), + __( + 'Double check the host, database name, username and password in {0}.', + CONFIG . 'passbolt.php' + ), + __('Make sure the database exists and is accessible for the given database user.'), + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'connect'; + } + + /** + * This method is only here because we don't have "datasource" access outside. + * + * @return bool + */ + protected function isDriverSupported(): bool + { + $result = false; + + $connection = ConnectionManager::get($this->getDatasource()); + $config = $connection->config(); + if (in_array($config['driver'], self::SUPPORTED_DRIVERS)) { + $result = true; + } + + return $result; + } +} diff --git a/src/Service/Healthcheck/Database/DefaultContentDatabaseHealthcheck.php b/src/Service/Healthcheck/Database/DefaultContentDatabaseHealthcheck.php new file mode 100644 index 0000000000..02de60c435 --- /dev/null +++ b/src/Service/Healthcheck/Database/DefaultContentDatabaseHealthcheck.php @@ -0,0 +1,78 @@ +getDatasource()); + $nRoles = $connection->selectQuery('id') + ->from('roles') + ->rowCountAndClose(); + $this->status = ($nRoles >= 3); + } catch (MissingConnectionException | \PDOException $e) { + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Some default content is present.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('No default content found.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Run the install script to install the database tables'), + 'sudo su -s /bin/bash -c "' . ROOT . DS . 'bin/cake passbolt install" ' . PROCESS_USER, + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'defaultContent'; + } +} diff --git a/src/Service/Healthcheck/Database/SchemaUpToDateApplicationHealthcheck.php b/src/Service/Healthcheck/Database/SchemaUpToDateApplicationHealthcheck.php new file mode 100644 index 0000000000..3f96642566 --- /dev/null +++ b/src/Service/Healthcheck/Database/SchemaUpToDateApplicationHealthcheck.php @@ -0,0 +1,136 @@ +status = !$this->needMigration(); + } catch (\Exception $e) { + // Do nothing + } + + return $this; + } + + /** + * Check if the app or plugins need a database migration + * + * @return bool + */ + public function needMigration(): bool + { + $Migrations = new Migrations(['connection' => ConnectionManager::get('default')->configName()]); + $migrations = $Migrations->status(); + foreach ($migrations as $migration) { + if ($migration['status'] === 'down') { + return true; + } + } + + return false; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The database schema up to date.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The database schema is not up to date.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Run the migration scripts:'), + 'sudo su -s /bin/bash -c "' . ROOT . DS . 'bin/cake migrations migrate --no-lock" ' . PROCESS_USER, + __('See https://www.passbolt.com/help/tech/update'), + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_APPLICATION; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'schema'; + } +} diff --git a/src/Service/Healthcheck/Database/TablesCountDatabaseHealthcheck.php b/src/Service/Healthcheck/Database/TablesCountDatabaseHealthcheck.php new file mode 100644 index 0000000000..45b4e491e5 --- /dev/null +++ b/src/Service/Healthcheck/Database/TablesCountDatabaseHealthcheck.php @@ -0,0 +1,87 @@ +getDatasource()); + $this->tableCount = count($connection->getSchemaCollection()->listTables()); + + $this->status = $this->tableCount > 0; + } catch (MissingConnectionException $connectionError) { + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('{0} tables found.', $this->tableCount); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('No table found.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Run the install script to install the database tables'), + 'sudo su -s /bin/bash -c "' . ROOT . DS . 'bin/cake passbolt install" ' . PROCESS_USER, + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'tablesCount'; + } + + /** + * @deprecated As of v4.7.0, just kept it here for BC. + * @return int + */ + public function getTableCount(): int + { + return $this->tableCount; + } +} diff --git a/src/Service/Healthcheck/Environment/ImageHealthcheck.php b/src/Service/Healthcheck/Environment/ImageHealthcheck.php new file mode 100644 index 0000000000..dd82de24d8 --- /dev/null +++ b/src/Service/Healthcheck/Environment/ImageHealthcheck.php @@ -0,0 +1,111 @@ +status = (extension_loaded('gd') || extension_loaded('imagick')); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return 'error'; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('GD or Imagick extension is installed.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('You must enable the gd or imagick extensions to use Passbolt.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('See. https://secure.php.net/manual/en/book.image.php'), + __('See. https://secure.php.net/manual/en/book.imagick.php'), + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'image'; + } +} diff --git a/src/Service/Healthcheck/Environment/IntlHealthcheck.php b/src/Service/Healthcheck/Environment/IntlHealthcheck.php new file mode 100644 index 0000000000..a1a93eb8f4 --- /dev/null +++ b/src/Service/Healthcheck/Environment/IntlHealthcheck.php @@ -0,0 +1,108 @@ +status = extension_loaded('intl'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return 'error'; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Intl extension is installed.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('You must enable the intl extension to use Passbolt.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [__('See. https://secure.php.net/manual/en/book.intl.php')]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'intl'; + } +} diff --git a/src/Service/Healthcheck/Environment/LogFolderWritableHealthcheck.php b/src/Service/Healthcheck/Environment/LogFolderWritableHealthcheck.php new file mode 100644 index 0000000000..2063f77988 --- /dev/null +++ b/src/Service/Healthcheck/Environment/LogFolderWritableHealthcheck.php @@ -0,0 +1,114 @@ +status = is_writable(LOGS); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The logs directory and its content are writable.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The logs directory and its content are not writable.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Ensure the logs directory and its content are writable by the user the webserver user.'), + __('you can try:'), + 'sudo chown -R ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . ROOT . 'logs', + 'sudo chmod 775 $(find ' . ROOT . 'logs -type d)', + 'sudo chmod 664 $(find ' . ROOT . 'logs -type f)', + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'logWritable'; + } +} diff --git a/src/Service/Healthcheck/Environment/MbstringHealthcheck.php b/src/Service/Healthcheck/Environment/MbstringHealthcheck.php new file mode 100644 index 0000000000..542eeb2454 --- /dev/null +++ b/src/Service/Healthcheck/Environment/MbstringHealthcheck.php @@ -0,0 +1,108 @@ +status = extension_loaded('mbstring'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Mbstring extension is installed.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('You must enable the mbstring extension to use Passbolt.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [__('See. https://secure.php.net/manual/en/book.mbstring.php')]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'mbstring'; + } +} diff --git a/src/Service/Healthcheck/Environment/NextMinPhpVersionHealthcheck.php b/src/Service/Healthcheck/Environment/NextMinPhpVersionHealthcheck.php new file mode 100644 index 0000000000..5f615ea856 --- /dev/null +++ b/src/Service/Healthcheck/Environment/NextMinPhpVersionHealthcheck.php @@ -0,0 +1,124 @@ +status = version_compare( + PHP_VERSION, + Configure::read(self::PHP_NEXT_MIN_VERSION_CONFIG), + '>=' + ); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __( + 'PHP version is {0} or above.', + Configure::read(self::PHP_NEXT_MIN_VERSION_CONFIG) + ); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __( + 'PHP version less than {0} will soon be not supported by passbolt, so consider upgrading your operating system or PHP environment.', // phpcs:ignore + Configure::read(self::PHP_NEXT_MIN_VERSION_CONFIG) + ); + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): ?string + { + return null; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'nextMinPhpVersion'; + } +} diff --git a/src/Service/Healthcheck/Environment/PcreHealthcheck.php b/src/Service/Healthcheck/Environment/PcreHealthcheck.php new file mode 100644 index 0000000000..3e687491f6 --- /dev/null +++ b/src/Service/Healthcheck/Environment/PcreHealthcheck.php @@ -0,0 +1,109 @@ +status = Validation::alphaNumeric('passbolt'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('PCRE compiled with unicode support.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('PCRE has not been compiled with Unicode support.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): ?string + { + return __('Recompile PCRE with Unicode support by adding --enable-unicode-properties when configuring.'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'pcre'; + } +} diff --git a/src/Service/Healthcheck/Environment/PhpVersionHealthcheck.php b/src/Service/Healthcheck/Environment/PhpVersionHealthcheck.php new file mode 100644 index 0000000000..16fbfab4d4 --- /dev/null +++ b/src/Service/Healthcheck/Environment/PhpVersionHealthcheck.php @@ -0,0 +1,119 @@ +status = version_compare( + PHP_VERSION, + Configure::read(self::PHP_MIN_VERSION_CONFIG), + '>=' + ); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('PHP version {0}.', PHP_VERSION); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __( + 'PHP version is too low, passbolt need PHP {0} or higher.', + Configure::read(self::PHP_MIN_VERSION_CONFIG) + ); + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): ?string + { + return null; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'phpVersion'; + } +} diff --git a/src/Service/Healthcheck/Environment/TmpFolderWritableHealthcheck.php b/src/Service/Healthcheck/Environment/TmpFolderWritableHealthcheck.php new file mode 100644 index 0000000000..96b1651606 --- /dev/null +++ b/src/Service/Healthcheck/Environment/TmpFolderWritableHealthcheck.php @@ -0,0 +1,135 @@ +status = true; + + /** @var \SplFileInfo[] $iterator */ + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator(TMP), + \RecursiveIteratorIterator::SELF_FIRST + ); + foreach ($iterator as $name => $fileInfo) { + if (in_array($fileInfo->getFilename(), ['.', '..', 'empty'])) { + continue; + } + // No file should be executable in tmp + if ($fileInfo->isFile() && DirectoryUtility::isExecutable($name)) { + $this->status = false; + } + if (!$fileInfo->isWritable()) { + $this->status = false; + } + } + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The temporary directory and its content are writable and not executable.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The temporary directory and its content are not writable, or are executable.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Ensure the temporary directory and its content are writable by the webserver user.'), + __('you can try:'), + 'sudo chown -R ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . TMP, + 'sudo chmod -R 775 $(find ' . TMP . ' -type d)', + 'sudo chmod -R 664 $(find ' . TMP . ' -type f)', + ]; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_ENVIRONMENT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'tmpWritable'; + } +} diff --git a/src/Service/Healthcheck/Gpg/AbstractGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/AbstractGpgHealthcheck.php new file mode 100644 index 0000000000..6e8eab8d10 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/AbstractGpgHealthcheck.php @@ -0,0 +1,148 @@ +getPublicServerKey(); + + return $publicServerKey !== null && is_readable($publicServerKey); + } + + /** + * @return bool + */ + protected function isPrivateServerKeyReadable(): bool + { + $privateServerKey = $this->getPrivateServerKey(); + + return $privateServerKey !== null && is_readable($privateServerKey); + } + + /** + * @return string|null + */ + protected function getServerKeyPassphrase(): ?string + { + return Configure::read('passbolt.gpg.serverKey.passphrase'); + } + + /** + * @return string|null + */ + protected function getGpgHome(): ?string + { + switch (Configure::read('passbolt.gpg.backend')) { + case OpenPGPBackendFactory::GNUPG: + // If no keyring location has been set, use the default one ~/.gnupg. + $gpgHome = getenv('GNUPGHOME'); + if (empty($gpgHome)) { + $uid = posix_getuid(); + $user = posix_getpwuid($uid); + $gpgHome = $user['dir'] . '/.gnupg'; + } + break; + case OpenPGPBackendFactory::HTTP: + // using cache for local keyring + $gpgHome = 'Cache engine'; + break; + default: + // unknown backend + $gpgHome = null; + break; + } + + return $gpgHome; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_GPG; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_ERROR; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_GPG; + } +} diff --git a/src/Service/Healthcheck/Gpg/CanDecryptGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/CanDecryptGpgHealthcheck.php new file mode 100644 index 0000000000..b7d24b2f21 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/CanDecryptGpgHealthcheck.php @@ -0,0 +1,113 @@ +canEncryptGpgHealthcheck = $canEncryptGpgHealthcheck; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if (!$this->canEncryptGpgHealthcheck->isPassed()) { + return $this; + } + + $gpg = OpenPGPBackendFactory::get(); + $messageToEncrypt = 'test message'; + try { + $fingerprint = $this->getServerKeyFingerprint(); + $passphrase = $this->getServerKeyPassphrase(); + $gpg->setEncryptKeyFromFingerprint($fingerprint); + $encryptedMessage = $gpg->encrypt($messageToEncrypt); + $gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase); + $decryptedMessage = $gpg->decrypt($encryptedMessage); + if ($decryptedMessage === $messageToEncrypt) { + $this->status = true; + } + } catch (CakeException $e) { + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The private key can be used to decrypt a message.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The private key cannot be used to decrypt a message'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return null; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'canDecrypt'; + } +} diff --git a/src/Service/Healthcheck/Gpg/CanDecryptVerifyGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/CanDecryptVerifyGpgHealthcheck.php new file mode 100644 index 0000000000..dac6d091a0 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/CanDecryptVerifyGpgHealthcheck.php @@ -0,0 +1,115 @@ +publicKeyInKeyringGpgHealthcheck = $publicKeyInKeyringGpgHealthcheck; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if (!$this->publicKeyInKeyringGpgHealthcheck->isPassed()) { + return $this; + } + + $gpg = OpenPGPBackendFactory::get(); + $messageToEncrypt = 'test message'; + try { + $fingerprint = $this->getServerKeyFingerprint(); + $passphrase = $this->getServerKeyPassphrase(); + $gpg->setEncryptKeyFromFingerprint($fingerprint); + $gpg->setSignKeyFromFingerprint($fingerprint, $passphrase); + $encryptedMessage2 = $gpg->encrypt($messageToEncrypt, true); + $gpg->setVerifyKeyFromFingerprint($fingerprint); + $gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase); + $decryptedMessage2 = $gpg->decrypt($encryptedMessage2, true); + if ($decryptedMessage2 === $messageToEncrypt) { + $this->status = true; + } + } catch (CakeException $e) { + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The private key can be used to decrypt and verify a message.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The private key cannot be used to decrypt and verify a message'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return null; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'canDecryptVerify'; + } +} diff --git a/src/Service/Healthcheck/Gpg/CanEncryptGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/CanEncryptGpgHealthcheck.php new file mode 100644 index 0000000000..6d11f16efb --- /dev/null +++ b/src/Service/Healthcheck/Gpg/CanEncryptGpgHealthcheck.php @@ -0,0 +1,114 @@ +publicKeyInKeyringGpgHealthcheck = $publicKeyInKeyringGpgHealthcheck; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if (!$this->publicKeyInKeyringGpgHealthcheck->isPassed()) { + $this->markAsSkipped(); + + return $this; + } + + $gpg = OpenPGPBackendFactory::get(); + try { + $gpg->setEncryptKeyFromFingerprint($this->getServerKeyFingerprint()); + $gpg->encrypt('test message'); + $this->status = true; + } catch (CakeException $e) { + // Do nothing + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The public key can be used to encrypt a message.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The public key cannot be used to encrypt a message'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Make sure that the server private key is valid and that there is no passphrase.'), + __('Make sure you imported the private server key in the keyring of the webserver user.'), + __('you can try:'), + 'sudo su -s /bin/bash -c "gpg --home ' . $this->getGpgHome() . ' --import ' . $this->getPrivateServerKey() . '" ' . PROCESS_USER, // phpcs:ignore + ]; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'canEncrypt'; + } +} diff --git a/src/Service/Healthcheck/Gpg/CanEncryptSignGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/CanEncryptSignGpgHealthcheck.php new file mode 100644 index 0000000000..77a74e5fa0 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/CanEncryptSignGpgHealthcheck.php @@ -0,0 +1,113 @@ +publicKeyInKeyringGpgHealthcheck = $publicKeyInKeyringGpgHealthcheck; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if (!$this->publicKeyInKeyringGpgHealthcheck->isPassed()) { + $this->markAsSkipped(); + + return $this; + } + + $gpg = OpenPGPBackendFactory::get(); + try { + $gpg->setEncryptKeyFromFingerprint($this->getServerKeyFingerprint()); + $gpg->setSignKeyFromFingerprint( + $this->getServerKeyFingerprint(), + $this->getServerKeyPassphrase() + ); + $gpg->encrypt('test message', true); + $this->status = true; + } catch (CakeException $e) { + // Do nothing + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The public and private keys can be used to encrypt and sign a message.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The public and private keys cannot be used to encrypt and sign a message'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return null; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'canEncryptSign'; + } +} diff --git a/src/Service/Healthcheck/Gpg/CanSignGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/CanSignGpgHealthcheck.php new file mode 100644 index 0000000000..07953764b7 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/CanSignGpgHealthcheck.php @@ -0,0 +1,117 @@ +publicKeyInKeyringGpgHealthcheck = $publicKeyInKeyringGpgHealthcheck; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if (!$this->publicKeyInKeyringGpgHealthcheck->isPassed()) { + $this->markAsSkipped(); + + return $this; + } + + $gpg = OpenPGPBackendFactory::get(); + $gpg->setSignKeyFromFingerprint( + $this->getServerKeyFingerprint(), + $this->getServerKeyPassphrase() + ); + try { + $gpg->sign('test message'); + $this->status = true; + } catch (CakeException $e) { + // Do nothing + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The private key can be used to sign a message.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The private key cannot be used to sign a message'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Make sure that the server private key is valid and that there is no passphrase.'), + __('Make sure you imported the private server key in the keyring of the webserver user.'), + __('you can try:'), + 'sudo su -s /bin/bash -c "gpg --home ' . $this->getGpgHome() . ' --import ' . $this->getPrivateServerKey() . '" ' . PROCESS_USER, // phpcs:ignore + ]; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'canSign'; + } +} diff --git a/src/Service/Healthcheck/Gpg/CanVerifyGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/CanVerifyGpgHealthcheck.php new file mode 100644 index 0000000000..b7902be568 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/CanVerifyGpgHealthcheck.php @@ -0,0 +1,114 @@ +canDecryptVerifyGpgHealthcheck = $canDecryptVerifyGpgHealthcheck; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if (!$this->canDecryptVerifyGpgHealthcheck->isPassed()) { + return $this; + } + + $gpg = OpenPGPBackendFactory::get(); + try { + $fingerprint = $this->getServerKeyFingerprint(); + $passphrase = $this->getServerKeyPassphrase(); + $gpg->setSignKeyFromFingerprint($fingerprint, $passphrase); + $signedMessage = $gpg->sign('test message'); + + try { + $gpg->setVerifyKeyFromFingerprint($fingerprint); + $gpg->verify($signedMessage); + $this->status = true; + } catch (CakeException $e) { + } + } catch (CakeException $e) { + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The public key can be used to verify a signature.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The public key cannot be used to verify a signature.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return null; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'canVerify'; + } +} diff --git a/src/Service/Healthcheck/Gpg/FingerprintMatchGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/FingerprintMatchGpgHealthcheck.php new file mode 100644 index 0000000000..02882eec71 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/FingerprintMatchGpgHealthcheck.php @@ -0,0 +1,120 @@ +getServerKeyFingerprint(); + if ($this->isPublicServerKeyReadable() && $this->isPrivateServerKeyReadable() && is_string($fingerprint)) { + $gpg = OpenPGPBackendFactory::get(); + $privateKeyData = file_get_contents($this->getPrivateServerKey()); + $privateKeyInfo = $gpg->getKeyInfo($privateKeyData); + $this->isPrivateKeyInfoOK = ($privateKeyInfo['fingerprint'] === $fingerprint); + $publicKeyData = file_get_contents($this->getPublicServerKey()); + $publicKeyInfo = $gpg->getPublicKeyInfo($publicKeyData); + $isPublicKeyInfoOK = ($publicKeyInfo['fingerprint'] === $fingerprint); + + $this->status = $isPublicKeyInfoOK && $this->isPrivateKeyInfoOK; + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The server key fingerprint matches the one defined in {0}.', CONFIG . 'passbolt.php'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The server key fingerprint doesn\'t match the one defined in {0}.', CONFIG . 'passbolt.php'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Double check the key fingerprint, example: '), + 'sudo su -s /bin/bash -c "gpg --list-keys --fingerprint --home ' . $this->getGpgHome() . '" ' . PROCESS_USER . ' | grep -i -B 2 \'SERVER_KEY_EMAIL\'',// phpcs:ignore + __('SERVER_KEY_EMAIL: The email you used when you generated the server key.'), + __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'gpgKeyPublicFingerprint'; + } + + /** + * @deprecated Just here to keep BC + * @return bool + */ + public function isPrivateKeyInfoOK(): bool + { + return $this->isPrivateKeyInfoOK; + } + + /** + * @deprecated Just here to keep BC + * @return bool + */ + public function gpgKeyPublicReadable(): bool + { + return $this->isPublicServerKeyReadable(); + } + + /** + * @deprecated Just here to keep BC + * @return bool + */ + public function gpgKeyPrivateReadable(): bool + { + return $this->isPublicServerKeyReadable(); + } + + /** + * @deprecated Just here to keep BC + * @return string|null + */ + public function gpgHome(): ?string + { + return $this->getGpgHome(); + } +} diff --git a/src/Service/Healthcheck/Gpg/GopengpgPrivateKeyFormatGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/GopengpgPrivateKeyFormatGpgHealthcheck.php new file mode 100644 index 0000000000..dfefd93165 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/GopengpgPrivateKeyFormatGpgHealthcheck.php @@ -0,0 +1,106 @@ +publicKeyInKeyringGpgHealthcheck = $publicKeyInKeyringGpgHealthcheck; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if (!$this->publicKeyInKeyringGpgHealthcheck->isPassed()) { + $this->markAsSkipped(); + + return $this; + } + + // Gpg keys should have only one return line + $privateKey = new Gpgkey(); + $privateKey->armored_key = file_get_contents($this->getPrivateServerKey()); + $rule = new GopengpgFormatRule(); + $this->status = $rule($privateKey); + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The server private key format is Gopengpg compatible.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The server private key format is not Gopengpg compatible.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return 'Remove all empty new lines above the end block line.'; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'isPrivateServerKeyGopengpgCompatible'; + } +} diff --git a/src/Service/Healthcheck/Gpg/GopengpgPublicKeyFormatGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/GopengpgPublicKeyFormatGpgHealthcheck.php new file mode 100644 index 0000000000..dcf95ab7d9 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/GopengpgPublicKeyFormatGpgHealthcheck.php @@ -0,0 +1,106 @@ +publicKeyInKeyringGpgHealthcheck = $publicKeyInKeyringGpgHealthcheck; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if (!$this->publicKeyInKeyringGpgHealthcheck->isPassed()) { + $this->markAsSkipped(); + + return $this; + } + + // Gpg keys should have only one return line + $publicKey = new Gpgkey(); + $publicKey->armored_key = file_get_contents($this->getPublicServerKey()); + $rule = new GopengpgFormatRule(); + $this->status = $rule($publicKey); + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The server public key format is Gopengpg compatible.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The server public key format is not Gopengpg compatible.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return 'Remove all empty new lines above the end block line.'; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'isPublicServerKeyGopengpgCompatible'; + } +} diff --git a/src/Service/Healthcheck/Gpg/HomeVariableDefinedGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/HomeVariableDefinedGpgHealthcheck.php new file mode 100644 index 0000000000..047b2c3221 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/HomeVariableDefinedGpgHealthcheck.php @@ -0,0 +1,93 @@ +gpgHome = $this->getGpgHome(); + if (is_null($this->gpgHome)) { + return $this; + } + + switch (Configure::read('passbolt.gpg.backend')) { + case OpenPGPBackendFactory::GNUPG: + $this->status = file_exists($this->getGpgHome()); + break; + case OpenPGPBackendFactory::HTTP: + $this->status = true; + break; + default: + break; + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The environment variable GNUPGHOME is set to {0}.', $this->gpgHome); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __( + 'The environment variable GNUPGHOME is set to {0}, but the directory does not exist.', + $this->gpgHome + ); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Ensure the keyring location exists and is accessible by the webserver user.'), + __('you can try:'), + 'sudo mkdir -p ' . $this->gpgHome, + 'sudo chown -R ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . $this->gpgHome, + 'sudo chmod 700 ' . $this->gpgHome, + __('You can change the location of the keyring by editing the GPG.env.setenv and GPG.env.home variables in {0}.', CONFIG . 'passbolt.php'),// phpcs:ignore + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'gpgHome'; + } +} diff --git a/src/Service/Healthcheck/Gpg/HomeVariableWritableGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/HomeVariableWritableGpgHealthcheck.php new file mode 100644 index 0000000000..b9688da97e --- /dev/null +++ b/src/Service/Healthcheck/Gpg/HomeVariableWritableGpgHealthcheck.php @@ -0,0 +1,104 @@ +status === false) { + $this->markAsSkipped(); + + return $this; + } + + if (Configure::read('passbolt.gpg.backend') === OpenPGPBackendFactory::GNUPG) { + $this->status = is_writable($this->gpgHome); + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The directory {0} containing the keyring is writable by the webserver user.', $this->gpgHome); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __( + 'The directory {0} containing the keyring is not writable by the webserver user.', + $this->gpgHome + ); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Ensure the keyring location is accessible by the webserver user.'), + __('you can try:'), + 'sudo chown -R ' . PROCESS_USER . ':' . PROCESS_USER . ' ' . $this->gpgHome, + 'sudo chmod 700 ' . $this->gpgHome, + ]; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'gpgHomeWritable'; + } +} diff --git a/src/Service/Healthcheck/Gpg/KeyNotDefaultGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/KeyNotDefaultGpgHealthcheck.php new file mode 100644 index 0000000000..9009eda83f --- /dev/null +++ b/src/Service/Healthcheck/Gpg/KeyNotDefaultGpgHealthcheck.php @@ -0,0 +1,81 @@ +getServerKeyFingerprint(); + $this-> isGpgkeyDefined = !is_null($fingerprint); + if (!$this->isGpgkeyDefined) { + return $this; + } + + $default = '2FC8945833C51946E937F9FED47B0811573EE67E'; + $this->status = ($fingerprint !== $default); + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The server OpenPGP key is not the default one.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + if ($this->isGpgkeyDefined) { + return __('Do not use the default OpenPGP key for the server.'); + } + + return __('The server OpenPGP key is not set.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Create a key, export it and add the fingerprint to {0}', CONFIG . 'passbolt.php'), + __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'gpgKeyNotDefault'; + } +} diff --git a/src/Service/Healthcheck/Gpg/PhpGpgModuleInstalledGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/PhpGpgModuleInstalledGpgHealthcheck.php new file mode 100644 index 0000000000..a37bd1eb4b --- /dev/null +++ b/src/Service/Healthcheck/Gpg/PhpGpgModuleInstalledGpgHealthcheck.php @@ -0,0 +1,73 @@ +status = true; + } catch (InternalErrorException $e) { + // Do nothing + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('PHP GPG Module is installed and loaded.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('PHP GPG Module is not installed or loaded.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return __('Install php-gnupg, see. http://php.net/manual/en/gnupg.installation.php') . + __('Make sure to add extension=gnupg.so in php ini files for both php-cli and php.'); + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'lib'; + } +} diff --git a/src/Service/Healthcheck/Gpg/PrivateKeyReadableAndParsableGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/PrivateKeyReadableAndParsableGpgHealthcheck.php new file mode 100644 index 0000000000..d4fb7096ce --- /dev/null +++ b/src/Service/Healthcheck/Gpg/PrivateKeyReadableAndParsableGpgHealthcheck.php @@ -0,0 +1,76 @@ +isPrivateServerKeyReadable()) { + return $this; + } + + $privateKeyData = file_get_contents($this->getPrivateServerKey()); + $blockStart = '-----BEGIN PGP PRIVATE KEY BLOCK-----'; + $this->status = strpos($privateKeyData, $blockStart) === 0; + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The private key file is defined in {0} and readable.', CONFIG . 'passbolt.php'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The private key file is not defined in {0} or not readable.', CONFIG . 'passbolt.php'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Ensure the private key file is defined by the variable passbolt.gpg.serverKey.private in {0}.', CONFIG . 'passbolt.php'),// phpcs:ignore + __('Ensure there is a private key armored block in the key file.'), + __('Ensure the private key defined in {0} exists and is accessible by the webserver user.', CONFIG . 'passbolt.php'),// phpcs:ignore + __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'gpgKeyPrivateBlock'; + } +} diff --git a/src/Service/Healthcheck/Gpg/PublicKeyEmailGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/PublicKeyEmailGpgHealthcheck.php new file mode 100644 index 0000000000..e54d7b06cf --- /dev/null +++ b/src/Service/Healthcheck/Gpg/PublicKeyEmailGpgHealthcheck.php @@ -0,0 +1,74 @@ +getServerKeyFingerprint(); + if ($this->isPublicServerKeyReadable() && $this->isPrivateServerKeyReadable() && is_string($fingerprint)) { + $gpg = OpenPGPBackendFactory::get(); + $publicKeyData = file_get_contents($this->getPublicServerKey()); + $publicKeyInfo = $gpg->getPublicKeyInfo($publicKeyData); + $this->status = is_string($publicKeyInfo['uid']) && + PublicKeyValidationService::uidContainValidEmail($publicKeyInfo['uid']); + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('There is a valid email id defined for the server key.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The server key does not have a valid email id.'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return 'Edit or generate another key with a valid email id.'; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'gpgKeyPublicEmail'; + } +} diff --git a/src/Service/Healthcheck/Gpg/PublicKeyInKeyringGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/PublicKeyInKeyringGpgHealthcheck.php new file mode 100644 index 0000000000..4985ee5f23 --- /dev/null +++ b/src/Service/Healthcheck/Gpg/PublicKeyInKeyringGpgHealthcheck.php @@ -0,0 +1,79 @@ +getServerKeyFingerprint(); + if (!$this->getGpgHome() || $fingerprint === null) { + return $this; + } + $gpg = OpenPGPBackendFactory::get(); + if (!$gpg->isKeyInKeyring($fingerprint)) { + return $this; + } + + $this->status = true; + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The server public key defined in the {0} (or environment variables) is in the keyring.', CONFIG . 'passbolt.php');// phpcs:ignore + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The server public key defined in the {0} (or environment variables) is not in the keyring', CONFIG . 'passbolt.php');// phpcs:ignore + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Import the private server key in the keyring of the webserver user.'), + __('you can try:'), + 'sudo su -s /bin/bash -c "gpg --home ' . $this->getGpgHome() . ' --import ' . $this->getPrivateServerKey() . '" ' . PROCESS_USER,// phpcs:ignore + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'gpgKeyPublicInKeyring'; + } +} diff --git a/src/Service/Healthcheck/Gpg/PublicKeyReadableAndParsableGpgHealthcheck.php b/src/Service/Healthcheck/Gpg/PublicKeyReadableAndParsableGpgHealthcheck.php new file mode 100644 index 0000000000..e32387233a --- /dev/null +++ b/src/Service/Healthcheck/Gpg/PublicKeyReadableAndParsableGpgHealthcheck.php @@ -0,0 +1,76 @@ +isPublicServerKeyReadable()) { + return $this; + } + + $publicKeyData = file_get_contents($this->getPublicServerKey()); + $blockStart = '-----BEGIN PGP PUBLIC KEY BLOCK-----'; + $this->status = (strpos($publicKeyData, $blockStart) === 0); + + return $this; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The public key file is defined in {0} and readable.', CONFIG . 'passbolt.php'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The public key file is not defined in {0} or not readable.', CONFIG . 'passbolt.php'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return [ + __('Ensure the public key file is defined by the variable passbolt.gpg.serverKey.public in {0}.', CONFIG . 'passbolt.php'),// phpcs:ignore + __('Ensure there is a public key armored block in the key file.'), + __('Ensure the public key defined in {0} exists and is accessible by the webserver user.', CONFIG . 'passbolt.php'),// phpcs:ignore + __('See. https://www.passbolt.com/help/tech/install#toc_gpg'), + ]; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'gpgKeyPublicBlock'; + } +} diff --git a/src/Service/Healthcheck/HealthcheckCliInterface.php b/src/Service/Healthcheck/HealthcheckCliInterface.php new file mode 100644 index 0000000000..252439a945 --- /dev/null +++ b/src/Service/Healthcheck/HealthcheckCliInterface.php @@ -0,0 +1,28 @@ +services[] = $healthcheckService; + } + + /** + * @param string $serviceClassName class FQN to retrieve + * @return \App\Service\Healthcheck\HealthcheckServiceInterface|null + */ + public function getService(string $serviceClassName): ?HealthcheckServiceInterface + { + foreach ($this->getServices() as $healthcheckService) { + if ($healthcheckService instanceof $serviceClassName) { + return $healthcheckService; + } + } + + return null; + } + + /** + * Returns all services available in this collector. + * + * @return \App\Service\Healthcheck\HealthcheckServiceInterface[] + */ + public function getServices(): array + { + return $this->services; + } + + /** + * Convenient method to retrieve services filtered by domains and service names + * + * @param array $domainsIncluded retrieve the services of the given domain + * @param array $servicesIncluded retrieve the services of the given + * @return array + */ + public function getServicesFiltered(array $domainsIncluded, array $servicesIncluded): array + { + $services = []; + foreach ($this->getServices() as $healthcheckService) { + if (in_array($healthcheckService->domain(), $domainsIncluded)) { + $services[] = $healthcheckService; + continue; + } + foreach ($servicesIncluded as $serviceIncluded) { + if (get_class($healthcheckService) === $serviceIncluded) { + $services[] = $healthcheckService; + } + } + } + + return $services; + } + + /** + * Returns title to show it to the user for this domain health check. + * + * @param string $domain Domain to get title from. + * @return string + */ + public function getTitleFromDomain(string $domain): string + { + $domainTitleMapping = $this->getDomainTitleMapping(); + + if (isset($domainTitleMapping[$domain])) { + return $domainTitleMapping[$domain]; + } + + // If mapping not found, change it to humanize form programmatically + return Inflector::humanize($domain); + } + + /** + * @return array + */ + protected function getDomainTitleMapping(): array + { + return [ + self::DOMAIN_ENVIRONMENT => __('Environment'), + self::DOMAIN_CONFIG_FILES => __('Config files'), + self::DOMAIN_CORE => __('Core config'), + self::DOMAIN_SMTP_SETTINGS => __('SMTP settings'), + self::DOMAIN_APPLICATION => __('Application configuration'), + self::DOMAIN_DATABASE => __('Database'), + self::DOMAIN_GPG => __('GPG Configuration'), + self::DOMAIN_JWT => __('JWT Authentication'), + self::DOMAIN_SSL => __('SSL Certificate'), + ]; + } + + /** + * @return array + */ + public function getDomainsInCollectedServices(): array + { + $domains = []; + foreach ($this->services as $service) { + if (!in_array($service->domain(), $domains)) { + $domains[] = $service->domain(); + } + } + + return $domains; + } +} diff --git a/src/Service/Healthcheck/HealthcheckServiceInterface.php b/src/Service/Healthcheck/HealthcheckServiceInterface.php new file mode 100644 index 0000000000..c2b98990d6 --- /dev/null +++ b/src/Service/Healthcheck/HealthcheckServiceInterface.php @@ -0,0 +1,78 @@ +status = $this->isFeaturePluginEnabled('JwtAuthentication'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_JWT; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The {0} plugin is enabled.', 'JWT Authentication'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The {0} plugin is disabled.', 'JWT Authentication'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): ?string + { + return __('Set the environment variable {0} to true', 'PASSBOLT_PLUGINS_JWT_AUTHENTICATION_ENABLED'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_JWT; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'isEnabled'; + } +} diff --git a/src/Service/Healthcheck/SkipHealthcheckInterface.php b/src/Service/Healthcheck/SkipHealthcheckInterface.php new file mode 100644 index 0000000000..f29edda06b --- /dev/null +++ b/src/Service/Healthcheck/SkipHealthcheckInterface.php @@ -0,0 +1,34 @@ +status = $this->isFeaturePluginEnabled('SmtpSettings'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_SMTP_SETTINGS; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('The {0} plugin is enabled.', 'SMTP Settings'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('The {0} plugin is disabled.', 'SMTP Settings'); + } + + /** + * @inheritDoc + */ + public function getHelpMessage(): ?string + { + return __('Enable the plugin in order to define SMTP settings in the database.'); + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_SMTP_SETTINGS; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'isEnabled'; + } +} diff --git a/src/Service/Healthcheck/Ssl/AbstractBaseSslHealthcheck.php b/src/Service/Healthcheck/Ssl/AbstractBaseSslHealthcheck.php new file mode 100644 index 0000000000..9ee09d02c4 --- /dev/null +++ b/src/Service/Healthcheck/Ssl/AbstractBaseSslHealthcheck.php @@ -0,0 +1,130 @@ +fullBaseUrlReachableCoreHealthcheck = $fullBaseUrlReachableCoreHealthcheck; + $this->client = $client; + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if ($this->fullBaseUrlReachableCoreHealthcheck->isHealthcheckEndpointUnreachable()) { + return $this; + } + + $url = Router::url('/healthcheck/status.json', true); + try { + $response = $this->client->get($url, [], $this->getClientOptions()); + $this->status = $response->isOk(); + } catch (\Exception $e) { + $this->helpMessage[] = $e->getMessage(); + } + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_SSL; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return $this->helpMessage; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_SSL; + } +} diff --git a/src/Service/Healthcheck/Ssl/HostValidSslHealthcheck.php b/src/Service/Healthcheck/Ssl/HostValidSslHealthcheck.php new file mode 100644 index 0000000000..30418f2b13 --- /dev/null +++ b/src/Service/Healthcheck/Ssl/HostValidSslHealthcheck.php @@ -0,0 +1,57 @@ + true, + 'ssl_verify_host' => true, + 'ssl_allow_self_signed' => true, + ]; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Hostname is matching in SSL certificate.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Hostname does not match when validating certificates.'); + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'hostValid'; + } +} diff --git a/src/Service/Healthcheck/Ssl/IsRequestHttpsSslHealthcheck.php b/src/Service/Healthcheck/Ssl/IsRequestHttpsSslHealthcheck.php new file mode 100644 index 0000000000..48c428a260 --- /dev/null +++ b/src/Service/Healthcheck/Ssl/IsRequestHttpsSslHealthcheck.php @@ -0,0 +1,149 @@ +request = $request; + } else { + $this->markAsSkipped(); + } + } + + /** + * @inheritDoc + */ + public function check(): HealthcheckServiceInterface + { + if ($this->isSkipped()) { + return $this; + } + + $this->status = $this->request->is('https'); + + return $this; + } + + /** + * @inheritDoc + */ + public function domain(): string + { + return HealthcheckServiceCollector::DOMAIN_SSL; + } + + /** + * @inheritDoc + */ + public function isPassed(): bool + { + return $this->status; + } + + /** + * @inheritDoc + */ + public function level(): string + { + return HealthcheckServiceCollector::LEVEL_WARNING; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('SSL access is enabled.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('SSL access is not enabled. You can still proceed, but it is highly recommended that you configure your web server to use HTTPS before you continue.'); // phpcs:ignore + } + + /** + * @inheritDoc + */ + public function getHelpMessage() + { + return null; + } + + /** + * CLI Option for this check. + * + * @return string + */ + public function cliOption(): string + { + return HealthcheckServiceCollector::DOMAIN_SSL; + } + + /** + * @inheritDoc + */ + public function markAsSkipped(): void + { + $this->isSkipped = true; + } + + /** + * @inheritDoc + */ + public function isSkipped(): bool + { + return $this->isSkipped; + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'is'; + } +} diff --git a/src/Service/Healthcheck/Ssl/NotSelfSignedSslHealthcheck.php b/src/Service/Healthcheck/Ssl/NotSelfSignedSslHealthcheck.php new file mode 100644 index 0000000000..62e8f83cc9 --- /dev/null +++ b/src/Service/Healthcheck/Ssl/NotSelfSignedSslHealthcheck.php @@ -0,0 +1,64 @@ + true, + 'ssl_verify_host' => true, + 'ssl_allow_self_signed' => false, + ]; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('Not using a self-signed certificate.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('Using a self-signed certificate.'); + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'notSelfSigned'; + } +} diff --git a/src/Service/Healthcheck/Ssl/PeerValidSslHealthcheck.php b/src/Service/Healthcheck/Ssl/PeerValidSslHealthcheck.php new file mode 100644 index 0000000000..ec664b7c20 --- /dev/null +++ b/src/Service/Healthcheck/Ssl/PeerValidSslHealthcheck.php @@ -0,0 +1,57 @@ + true, + 'ssl_verify_host' => false, + 'ssl_allow_self_signed' => true, + ]; + } + + /** + * @inheritDoc + */ + public function getSuccessMessage(): string + { + return __('SSL peer certificate validates.'); + } + + /** + * @inheritDoc + */ + public function getFailureMessage(): string + { + return __('SSL peer certificate does not validate.'); + } + + /** + * @inheritDoc + */ + public function getLegacyArrayKey(): string + { + return 'peerValid'; + } +} diff --git a/src/Service/Setup/AbstractRecoverStartService.php b/src/Service/Setup/AbstractRecoverStartService.php index 45f8ba410a..2fca1e935d 100644 --- a/src/Service/Setup/AbstractRecoverStartService.php +++ b/src/Service/Setup/AbstractRecoverStartService.php @@ -17,8 +17,6 @@ namespace App\Service\Setup; -use Cake\View\ViewBuilder; - abstract class AbstractRecoverStartService { /** @@ -42,18 +40,6 @@ public function getInfo(string $userId, string $token): ?array return $result; } - /** - * @param \Cake\View\ViewBuilder $viewBuilder View builder - * @return void - */ - public function setTemplate(ViewBuilder $viewBuilder): void - { - $viewBuilder - ->setTemplatePath('/Setup') - ->setLayout('default') - ->setTemplate('recoverStart'); - } - /** * Add service to get data from. * diff --git a/src/ServiceProvider/CommandServiceProvider.php b/src/ServiceProvider/CommandServiceProvider.php index 7950c20dc1..dcb6652461 100644 --- a/src/ServiceProvider/CommandServiceProvider.php +++ b/src/ServiceProvider/CommandServiceProvider.php @@ -19,15 +19,27 @@ use App\Command\HealthcheckCommand; use App\Command\InstallCommand; +use App\Command\KeyringInitCommand; +use App\Command\MigrateCommand; +use App\Command\MigratePostgresCommand; +use App\Command\RecoverUserCommand; +use App\Command\RegisterUserCommand; +use App\Service\Command\ProcessUserService; +use App\Service\Healthcheck\HealthcheckServiceCollector; use Cake\Core\ContainerInterface; use Cake\Core\ServiceProvider; -use Cake\Http\Client; class CommandServiceProvider extends ServiceProvider { protected $provides = [ + ProcessUserService::class, HealthcheckCommand::class, InstallCommand::class, + KeyringInitCommand::class, + MigrateCommand::class, + RecoverUserCommand::class, + MigratePostgresCommand::class, + RegisterUserCommand::class, ]; /** @@ -35,7 +47,20 @@ class CommandServiceProvider extends ServiceProvider */ public function services(ContainerInterface $container): void { - $container->add(HealthcheckCommand::class)->addArgument(Client::class); - $container->add(InstallCommand::class)->addArgument(Client::class); + $container->add(ProcessUserService::class); + + $container->add(HealthcheckCommand::class)->addArguments([ + ProcessUserService::class, + HealthcheckServiceCollector::class, + ]); + $container->add(InstallCommand::class)->addArguments([ + ProcessUserService::class, + HealthcheckServiceCollector::class, + ]); + $container->add(KeyringInitCommand::class)->addArgument(ProcessUserService::class); + $container->add(MigrateCommand::class)->addArgument(ProcessUserService::class); + $container->add(RecoverUserCommand::class)->addArgument(ProcessUserService::class); + $container->add(MigratePostgresCommand::class)->addArgument(ProcessUserService::class); + $container->add(RegisterUserCommand::class)->addArgument(ProcessUserService::class); } } diff --git a/src/ServiceProvider/HealthcheckServiceProvider.php b/src/ServiceProvider/HealthcheckServiceProvider.php new file mode 100644 index 0000000000..4f89ff70a3 --- /dev/null +++ b/src/ServiceProvider/HealthcheckServiceProvider.php @@ -0,0 +1,263 @@ +add(PhpVersionHealthcheck::class); + $container->add(NextMinPhpVersionHealthcheck::class); + $container->add(PcreHealthcheck::class); + $container->add(MbstringHealthcheck::class); + $container->add(IntlHealthcheck::class); + $container->add(ImageHealthcheck::class); + $container->add(TmpFolderWritableHealthcheck::class); + $container->add(LogFolderWritableHealthcheck::class); + // Config files health checks + $container->add(AppConfigFileHealthcheck::class); + $container->add(PassboltConfigFileHealthcheck::class); + // Core health checks + $container->add(CacheCoreHealthcheck::class); + $container->add(DebugDisabledCoreHealthcheck::class); + $container->add(SaltCoreHealthcheck::class); + $container->add(FullBaseUrlCoreHealthcheck::class); + $container->add(ValidFullBaseUrlCoreHealthcheck::class); + $container->add('fullBaseUrlReachableClient', Client::class); + $container->addShared(FullBaseUrlReachableCoreHealthcheck::class)->addArgument('fullBaseUrlReachableClient'); + // SSL health checks + $container->add('sslHealthcheckClient', Client::class); + $container->add(PeerValidSslHealthcheck::class) + ->addArguments([FullBaseUrlReachableCoreHealthcheck::class, 'sslHealthcheckClient']); + $container->add(HostValidSslHealthcheck::class) + ->addArguments([FullBaseUrlReachableCoreHealthcheck::class, 'sslHealthcheckClient']); + $container->add(NotSelfSignedSslHealthcheck::class) + ->addArguments([FullBaseUrlReachableCoreHealthcheck::class, 'sslHealthcheckClient']); + // Smtp Settings default healthcheck + $container->add(PluginEnabledSmtpSettingsHealthcheck::class); + // JWT default healthcheck + $container->add(PluginEnabledJwtHealthcheck::class); + // Gpg health checks + $container->add(PhpGpgModuleInstalledGpgHealthcheck::class); + $container->add(HomeVariableDefinedGpgHealthcheck::class); + $container->add(HomeVariableWritableGpgHealthcheck::class); + $container->add(KeyNotDefaultGpgHealthcheck::class); + $container->add(PublicKeyReadableAndParsableGpgHealthcheck::class); + $container->add(PrivateKeyReadableAndParsableGpgHealthcheck::class); + $container->add(FingerprintMatchGpgHealthcheck::class); + $container->addShared(PublicKeyInKeyringGpgHealthcheck::class); + $container->add(PublicKeyEmailGpgHealthcheck::class); + $container->addShared(CanEncryptGpgHealthcheck::class) + ->addArgument(PublicKeyInKeyringGpgHealthcheck::class); + $container->add(CanSignGpgHealthcheck::class) + ->addArgument(PublicKeyInKeyringGpgHealthcheck::class); + $container->add(CanEncryptSignGpgHealthcheck::class) + ->addArgument(PublicKeyInKeyringGpgHealthcheck::class); + $container->add(CanDecryptGpgHealthcheck::class) + ->addArgument(CanEncryptGpgHealthcheck::class); + $container->addShared(CanDecryptVerifyGpgHealthcheck::class) + ->addArgument(PublicKeyInKeyringGpgHealthcheck::class); + $container->add(CanVerifyGpgHealthcheck::class) + ->addArgument(CanDecryptVerifyGpgHealthcheck::class); + $container->add(GopengpgPublicKeyFormatGpgHealthcheck::class) + ->addArgument(PublicKeyInKeyringGpgHealthcheck::class); + $container->add(GopengpgPrivateKeyFormatGpgHealthcheck::class) + ->addArgument(PublicKeyInKeyringGpgHealthcheck::class); + // Application health checks + $container->add(LatestVersionApplicationHealthcheck::class); + $container->add(SslForceApplicationHealthcheck::class); + $container->add(SslFullBaseUrlApplicationHealthcheck::class); + $container->add(SeleniumDisabledApplicationHealthcheck::class); + $container->add(RobotsIndexDisabledApplicationHealthcheck::class); + $container->addShared(SelfRegistrationHealthcheckService::class); + $container + ->add(SelfRegistrationPluginEnabledApplicationHealthcheck::class) + ->addArgument(SelfRegistrationHealthcheckService::class); + $container + ->add(SelfRegistrationProviderApplicationHealthcheck::class) + ->addArgument(SelfRegistrationHealthcheckService::class); + $container + ->add(SelfRegistrationPublicRemovedApplicationHealthcheck::class) + ->addArgument(SelfRegistrationHealthcheckService::class); + $container->add(HostAvailabilityCheckEnabledApplicationHealthcheck::class); + $container->add(JsProdApplicationHealthcheck::class); + $container->add(EmailNotificationEnabledApplicationHealthcheck::class); + // Database health checks + $container->add(ConnectDatabaseHealthcheck::class); + $container->add(TablesCountDatabaseHealthcheck::class); + $container->add(DefaultContentDatabaseHealthcheck::class); + $container->add(SchemaUpToDateApplicationHealthcheck::class); + + // Append core health checks to service collector + $container->add(HealthcheckServiceCollector::class) + ->addMethodCall('addService', [PhpVersionHealthcheck::class]) + ->addMethodCall('addService', [NextMinPhpVersionHealthcheck::class]) + ->addMethodCall('addService', [PcreHealthcheck::class]) + ->addMethodCall('addService', [MbstringHealthcheck::class]) + ->addMethodCall('addService', [IntlHealthcheck::class]) + ->addMethodCall('addService', [ImageHealthcheck::class]) + ->addMethodCall('addService', [TmpFolderWritableHealthcheck::class]) + ->addMethodCall('addService', [LogFolderWritableHealthcheck::class]) + ->addMethodCall('addService', [AppConfigFileHealthcheck::class]) + ->addMethodCall('addService', [PassboltConfigFileHealthcheck::class]) + ->addMethodCall('addService', [CacheCoreHealthcheck::class]) + ->addMethodCall('addService', [DebugDisabledCoreHealthcheck::class]) + ->addMethodCall('addService', [SaltCoreHealthcheck::class]) + ->addMethodCall('addService', [FullBaseUrlCoreHealthcheck::class]) + ->addMethodCall('addService', [ValidFullBaseUrlCoreHealthcheck::class]) + ->addMethodCall('addService', [FullBaseUrlReachableCoreHealthcheck::class]) + ->addMethodCall('addService', [PeerValidSslHealthcheck::class]) + ->addMethodCall('addService', [HostValidSslHealthcheck::class]) + ->addMethodCall('addService', [NotSelfSignedSslHealthcheck::class]) + ->addMethodCall('addService', [PluginEnabledSmtpSettingsHealthcheck::class]) + ->addMethodCall('addService', [PluginEnabledJwtHealthcheck::class]) + ->addMethodCall('addService', [PhpGpgModuleInstalledGpgHealthcheck::class]) + ->addMethodCall('addService', [HomeVariableDefinedGpgHealthcheck::class]) + ->addMethodCall('addService', [HomeVariableWritableGpgHealthcheck::class]) + ->addMethodCall('addService', [KeyNotDefaultGpgHealthcheck::class]) + ->addMethodCall('addService', [PublicKeyReadableAndParsableGpgHealthcheck::class]) + ->addMethodCall('addService', [PrivateKeyReadableAndParsableGpgHealthcheck::class]) + ->addMethodCall('addService', [FingerprintMatchGpgHealthcheck::class]) + ->addMethodCall('addService', [PublicKeyInKeyringGpgHealthcheck::class]) + ->addMethodCall('addService', [PublicKeyEmailGpgHealthcheck::class]) + ->addMethodCall('addService', [CanEncryptGpgHealthcheck::class]) + ->addMethodCall('addService', [CanSignGpgHealthcheck::class]) + ->addMethodCall('addService', [CanEncryptSignGpgHealthcheck::class]) + ->addMethodCall('addService', [CanDecryptGpgHealthcheck::class]) + ->addMethodCall('addService', [CanDecryptVerifyGpgHealthcheck::class]) + ->addMethodCall('addService', [CanVerifyGpgHealthcheck::class]) + ->addMethodCall('addService', [GopengpgPublicKeyFormatGpgHealthcheck::class]) + ->addMethodCall('addService', [GopengpgPrivateKeyFormatGpgHealthcheck::class]) + ->addMethodCall('addService', [LatestVersionApplicationHealthcheck::class]) + ->addMethodCall('addService', [SslForceApplicationHealthcheck::class]) + ->addMethodCall('addService', [SslFullBaseUrlApplicationHealthcheck::class]) + ->addMethodCall('addService', [SeleniumDisabledApplicationHealthcheck::class]) + ->addMethodCall('addService', [RobotsIndexDisabledApplicationHealthcheck::class]) + ->addMethodCall('addService', [SelfRegistrationPluginEnabledApplicationHealthcheck::class]) + ->addMethodCall('addService', [SelfRegistrationProviderApplicationHealthcheck::class]) + ->addMethodCall('addService', [SelfRegistrationPublicRemovedApplicationHealthcheck::class]) + ->addMethodCall('addService', [HostAvailabilityCheckEnabledApplicationHealthcheck::class]) + ->addMethodCall('addService', [JsProdApplicationHealthcheck::class]) + ->addMethodCall('addService', [EmailNotificationEnabledApplicationHealthcheck::class]) + ->addMethodCall('addService', [ConnectDatabaseHealthcheck::class]) + ->addMethodCall('addService', [TablesCountDatabaseHealthcheck::class]) + ->addMethodCall('addService', [DefaultContentDatabaseHealthcheck::class]) + ->addMethodCall('addService', [SchemaUpToDateApplicationHealthcheck::class]); + + // Required for Healthcheck endpoint + $container->add(IsRequestHttpsSslHealthcheck::class)->addArgument(ServerRequest::class); + } +} diff --git a/src/Utility/Healthchecks.php b/src/Utility/Healthchecks.php deleted file mode 100644 index 2815fd32ca..0000000000 --- a/src/Utility/Healthchecks.php +++ /dev/null @@ -1,379 +0,0 @@ -all($checks); - $checks = (new SslHealthchecks($client))->all($checks); - $checks = Healthchecks::database('default', $checks); - $checks = Healthchecks::gpg($checks); - $checks = Healthchecks::application($checks); - $checks = Healthchecks::smtpSettings($checks); - - return $checks; - } - - /** - * Application checks - * - latestVersion: true if using latest version - * - schema: schema up to date no need to do a migration - * - info.remoteVersion - * - sslForce: enforcing the use of SSL - * - seleniumDisabled: true if selenium API is disabled - * - registrationClosed: info on the self registration - * - jsProd: true if using minified/concatenated javascript - * - * @param array|null $checks List of checks - * @return array - * @access private - */ - public static function application(?array $checks = []): array - { - try { - $checks['application']['info']['remoteVersion'] = Migration::getLatestTagName(); - $checks['application']['latestVersion'] = Migration::isLatestVersion(); - } catch (\Exception $e) { - $checks['application']['info']['remoteVersion'] = 'undefined'; - $checks['application']['latestVersion'] = null; - } - try { - $checks['application']['schema'] = !Migration::needMigration(); - } catch (\Exception $e) { - // Cannot connect to the database - $checks['application']['schema'] = false; - } - $robots = strpos(Configure::read('passbolt.meta.robots'), 'noindex'); - $checks['application']['robotsIndexDisabled'] = ($robots !== false); - $checks['application']['sslForce'] = Configure::read('passbolt.ssl.force'); - $https = strpos(Configure::read('App.fullBaseUrl'), 'https') === 0; - $checks['application']['sslFullBaseUrl'] = ($https !== false); - $checks['application']['configPath'] = CONFIG . 'passbolt.php'; - $checks['application']['info']['currentVersion'] = Configure::read('passbolt.version'); - $checks['application']['seleniumDisabled'] = !Configure::read('passbolt.selenium.active'); - $checks['application']['registrationClosed'] = (new SelfRegistrationHealthcheckService())->getHealthcheck(); - $checks['application']['hostAvailabilityCheckEnabled'] = Configure::read(EmailValidationRule::MX_CHECK_KEY); - $checks['application']['jsProd'] = (Configure::read('passbolt.js.build') === 'production'); - $sendEmailJson = json_encode(Configure::read('passbolt.email.send')); - $checks['application']['emailNotificationEnabled'] = !(preg_match('/false/', $sendEmailJson) === 1); - - $checks = array_merge(Healthchecks::appUser(), $checks); - - return $checks; - } - - /** - * Check that users are set in the database - * - app.adminCount there is at least an admin in the database - * - * @param array|null $checks List of checks - * @return array - */ - public static function appUser(?array $checks = []): array - { - // no point checking for records if can not connect - $checks = array_merge(Healthchecks::database(), $checks); - $checks['application']['adminCount'] = false; - if (!$checks['database']['connect']) { - return $checks; - } - - // check number of admin user - $User = TableRegistry::getTableLocator()->get('Users'); - try { - $i = $User->find('all') - ->contain(['Roles']) - ->where(['Roles.name' => Role::ADMIN]) - ->count(); - - $checks['application']['adminCount'] = ($i > 0); - } catch (CakeException $e) { - } - - return $checks; - } - - /** - * Return config file checks: - * - configFile.app true if file is present, false otherwise - * - * @param array|null $checks List of checks - * @return array - */ - public static function configFiles(?array $checks = []): array - { - $files = ['app', 'passbolt']; - foreach ($files as $file) { - $checks['configFile'][$file] = (file_exists(CONFIG . $file . '.php')); - } - - return $checks; - } - - /** - * Check core file configuration - * - cache: settings are set - * - debugDisabled: the core.debug is set to 0 - * - salt: true if non default salt is used - * - cipherSeed: true if non default cipherSeed is used - * - * @param ?\Cake\Http\Client $client Client - * @param array|null $checks List of checks - * @return array - */ - public static function core(?Client $client = null, ?array $checks = []): array - { - return (new CoreHealthchecks($client))->all($checks); - } - - /** - * Return database checks: - * - connect: can connect to the database - * - tablesPrefixes: not using tablesPrefix - * - tableCount: at least one table is present - * - info.tableCount: number of tables installed - * - defaultContent: some default content (4 roles) - * - * @param string|null $datasource Datasource name - * @param array|null $checks List of checks - * @return array - */ - public static function database(?string $datasource = 'default', ?array $checks = []): array - { - return DatabaseHealthchecks::all($datasource, $checks); - } - - /** - * Return core checks: - * - phpVersion: php version is superior to 7.0 - * - pcre: unicode support - * - tmpWritable: the TMP directory is writable for the current user - * - * @param array|null $checks List of checks - * @return array - */ - public static function environment(?array $checks = []): array - { - $checks['environment']['phpVersion'] = version_compare( - PHP_VERSION, - Configure::read(self::PHP_MIN_VERSION_CONFIG), - '>=' - ); - $checks['environment']['nextMinPhpVersion'] = version_compare( - PHP_VERSION, - Configure::read(self::PHP_NEXT_MIN_VERSION_CONFIG), - '>=' - ); - $checks['environment']['info']['phpVersion'] = PHP_VERSION; - $checks['environment']['pcre'] = Validation::alphaNumeric('passbolt'); - $checks['environment']['mbstring'] = extension_loaded('mbstring'); - $checks['environment']['gnupg'] = extension_loaded('gnupg'); - $checks['environment']['intl'] = extension_loaded('intl'); - $checks['environment']['image'] = (extension_loaded('gd') || extension_loaded('imagick')); - $checks['environment']['tmpWritable'] = self::_checkRecursiveDirectoryWritable(TMP); - $checks['environment']['logWritable'] = is_writable(LOGS); - //$checks['environment']['allow_url_fopen'] = ini_get('allow_url_fopen') === '1'; - - return $checks; - } - - /** - * Returns JWT related checks: - * - is the JWT Authentication enabled - * - if true, are the JWT key files correctly set and valid. - * - * @param \Passbolt\JwtAuthentication\Service\AccessToken\JwtKeyPairService|null $jwtKeyPairService JWT Service - * @param array $checks List of checks - * @return array - */ - public static function jwt(?JwtKeyPairService $jwtKeyPairService = null, array $checks = []): array - { - if (is_null($jwtKeyPairService)) { - $jwtKeyPairService = new JwtKeyPairService(); - } - try { - $jwtKeyPairService->validateKeyPair(); - $keyPairIsValid = true; - } catch (\Throwable $e) { - $keyPairIsValid = false; - } - - $checks['jwt']['isEnabled'] = (Configure::read('passbolt.plugins.jwtAuthentication.enabled') === true); - $checks['jwt']['keyPairValid'] = $keyPairIsValid; - $checks['jwt']['jwtWritable'] = is_writable(JwtAbstractService::JWT_CONFIG_DIR); - - return $checks; - } - - /** - * Gpg checks - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpg(?array $checks = []): array - { - return GpgHealthchecks::all($checks); - } - - /** - * SSL certs check - * - ssl.peerValid - * - ssl.hostValid - * - ssl.notSelfSigned - * - * @param ?\Cake\Http\Client $client Client - * @param array|null $checks List of checks - * @return array - */ - public static function ssl(?Client $client = null, ?array $checks = []): array - { - return (new SslHealthchecks($client))->all($checks); - } - - /** - * SmtpSettings check - * - PASS: SMTP settings are set in the DB and decryptable - * - WARN: SMTP settings are not set in the DB - * - FAIL: SMTP settings are set in the DB and not decryptable - * - * @param array|null $checks List of checks - * @return array - */ - public static function smtpSettings(?array $checks = []): array - { - // Since the plugin might be removed from various passbolt solutions, we check - // the availability of the plugin before calling classes of the plugin - if (!(new self())->isFeaturePluginEnabled('SmtpSettings')) { - $checks['smtpSettings']['isEnabled'] = false; - - return $checks; - } - - return (new SmtpSettingsHealthcheckService())->check($checks); - } - - /** - * Check that a directory and its content are writable - * - * @param string $path the directory path - * @return bool - */ - private static function _checkRecursiveDirectoryWritable(string $path): bool - { - clearstatcache(); - - /** @var \SplFileInfo[] $iterator */ - $iterator = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($path), - \RecursiveIteratorIterator::SELF_FIRST - ); - foreach ($iterator as $name => $fileInfo) { - if (in_array($fileInfo->getFilename(), ['.', '..', 'empty'])) { - continue; - } - // No file should be executable in tmp - if ($fileInfo->isFile() && DirectoryUtility::isExecutable($name)) { - return false; - } - if (!$fileInfo->isWritable()) { - return false; - } - } - - return true; - } - - /** - * Get schema tables list. (per version number). - * - * @param int $version passbolt major version number. - * @return array - */ - public static function getSchemaTables(int $version = 2): array - { - // List of tables for passbolt v1. - $tables = [ - 'authentication_tokens', - 'avatars', - 'comments', - 'email_queue', - 'favorites', - 'gpgkeys', - 'groups', - 'groups_users', - 'permissions', - 'profiles', - 'resources', - 'roles', - 'secrets', - 'users', - ]; - - // Extra tables for passbolt v2. - if ($version == 2) { - $tables = array_merge($tables, [ - //'burzum_file_storage_phinxlog', // dropped in v2.8 - //'email_queue_phinxlog', - 'phinxlog', - ]); - } - - return $tables; - } -} diff --git a/src/Utility/Healthchecks/CoreHealthchecks.php b/src/Utility/Healthchecks/CoreHealthchecks.php deleted file mode 100644 index 4b924e415c..0000000000 --- a/src/Utility/Healthchecks/CoreHealthchecks.php +++ /dev/null @@ -1,91 +0,0 @@ -client = $client; - } - - /** - * Check core file configuration - * - * - cache: settings are set - * - debugDisabled: the core.debug is set to 0 - * - salt: true if non default salt is used - * - cipherSeed: true if non default cipherSeed is used - * - * @param array|null $checks List of checks - * @return array - */ - public function all(?array $checks = []): array - { - $settings = Cache::getConfig('_cake_core_'); - $checks['core']['cache'] = !empty($settings); - $checks['core']['debugDisabled'] = (Configure::read('debug') === false); - $checks['core']['salt'] = (Configure::read('Security.salt') !== '__SALT__'); - $checks['core']['fullBaseUrl'] = (Configure::read('App.fullBaseUrl') !== null); - $checks['core']['validFullBaseUrl'] = Validation::url(Configure::read('App.fullBaseUrl'), true); - $checks['core']['info']['fullBaseUrl'] = Configure::read('App.fullBaseUrl'); - - // Check if the URL is reachable - $checks['core']['fullBaseUrlReachable'] = false; - try { - $isResponseOK = false; - $url = Router::url('/healthcheck/status.json', true); - if (isset($this->client)) { - // If the client is mocked in tests - $isResponseOK = $this->client->get($url)->isOk(); - } else { - $context = stream_context_create([ - 'http' => [ - 'method' => 'GET', - ], - 'ssl' => [ - 'verify_peer' => false, - 'verify_peer_name' => false, - ], - ]); - $response = @file_get_contents($url, false, $context); // phpcs:ignore - if ($response !== false && !empty($response)) { - $json = json_decode($response); - if (isset($json->body)) { - $isResponseOK = ($json->body === 'OK'); - } - } - } - $checks['core']['fullBaseUrlReachable'] = $isResponseOK; - } catch (CakeException $e) { - } - - return $checks; - } -} diff --git a/src/Utility/Healthchecks/DatabaseHealthchecks.php b/src/Utility/Healthchecks/DatabaseHealthchecks.php deleted file mode 100644 index b4e5eceb7c..0000000000 --- a/src/Utility/Healthchecks/DatabaseHealthchecks.php +++ /dev/null @@ -1,156 +0,0 @@ - [ - 'connect' => false, - 'info' => [], - ], - ], - $checks - ); - try { - /** @var \Cake\Database\Connection $connection */ - $connection = ConnectionManager::get($datasource); - $connection->getDriver()->connect(); - $checks['database']['connect'] = true; - } catch (MissingConnectionException $connectionError) { - $checks['database']['info']['connection'] = __('Database connection failed'); - - if (method_exists($connectionError, 'getAttributes')) { - $attributes = $connectionError->getAttributes(); - - if (isset($attributes['reason'])) { - $checks['database']['info']['connection'] = $attributes['reason']; - } - } - } - - return $checks; - } - - /** - * Is the database engine supported - * - * @param string $datasource Datasource name - * @param array|null $checks List of checks - * @return array - */ - private static function supportedBackend(string $datasource, ?array $checks = []): array - { - $checks['database']['supportedBackend'] = false; - $connection = ConnectionManager::get($datasource); - $config = $connection->config(); - if (in_array($config['driver'], ['Cake\Database\Driver\Mysql', 'Cake\Database\Driver\Postgres'])) { - $checks['database']['supportedBackend'] = true; - } - - return $checks; - } - - /** - * Check if tables are present - - * @param string $datasource Datasource name - * @param array|null $checks List of checks - * @return array - */ - private static function tableCount(string $datasource, ?array $checks = []): array - { - $checks = array_replace_recursive( - [ - 'database' => [ - 'tablesCount' => false, - 'info' => [ - 'tablesCount' => 0, - ], - ], - ], - $checks - ); - try { - $connection = ConnectionManager::get('default'); - $tables = $connection->getSchemaCollection()->listTables(); - - if (count($tables) > 0) { - $checks['database']['tablesCount'] = true; - $checks['database']['info']['tablesCount'] = count($tables); - } - } catch (DatabaseException | MissingConnectionException $connectionError) { - } - - return $checks; - } - - /** - * Check if some default data is present - * We only check the number of roles - * - * @param array|null $checks List of checks - * @return array - */ - private static function defaultContent(?array $checks = []): array - { - $checks['database']['defaultContent'] = false; - try { - $nRoles = TableRegistry::getTableLocator() - ->get('Roles') - ->find() - ->count(); - $checks['database']['defaultContent'] = ($nRoles >= 3); - } catch (DatabaseException | MissingConnectionException | \PDOException $e) { - } - - return $checks; - } -} diff --git a/src/Utility/Healthchecks/GpgHealthchecks.php b/src/Utility/Healthchecks/GpgHealthchecks.php deleted file mode 100644 index 208ba4fa8b..0000000000 --- a/src/Utility/Healthchecks/GpgHealthchecks.php +++ /dev/null @@ -1,465 +0,0 @@ - [ - 'gpgKeyPrivateFingerprint' => false, - 'gpgKeyPublicFingerprint' => false, - 'gpgKeyPublicEmail' => false, - 'gpgKeyPublicReadable' => false, - 'gpgKeyPrivateReadable' => false, - 'gpgKey' => false, - ], - ], - $checks - ); - $areKeysReadable = $checks['gpg']['gpgKeyPublicReadable'] && $checks['gpg']['gpgKeyPrivateReadable']; - if ($areKeysReadable && $checks['gpg']['gpgKey']) { - $gpg = OpenPGPBackendFactory::get(); - $privateKeydata = file_get_contents(Configure::read('passbolt.gpg.serverKey.private')); - $privateKeyInfo = $gpg->getKeyInfo($privateKeydata); - if ($privateKeyInfo['fingerprint'] === Configure::read('passbolt.gpg.serverKey.fingerprint')) { - $checks['gpg']['gpgKeyPrivateFingerprint'] = true; - } - $publicKeydata = file_get_contents(Configure::read('passbolt.gpg.serverKey.public')); - $publicKeyInfo = $gpg->getPublicKeyInfo($publicKeydata); - if ($publicKeyInfo['fingerprint'] === Configure::read('passbolt.gpg.serverKey.fingerprint')) { - $checks['gpg']['gpgKeyPublicFingerprint'] = true; - } - - $checks['gpg']['gpgKeyPublicEmail'] = is_string($publicKeyInfo['uid']) && - PublicKeyValidationService::uidContainValidEmail($publicKeyInfo['uid']); - } - - return $checks; - } - - /** - * Check that the server public/private keys are present in the keyring. - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpgKeyInKeyring(?array $checks = []): array - { - $checks = array_replace_recursive( - [ - 'gpg' => [ - 'gpgHome' => false, - 'gpgKeyPublicInKeyring' => false, - ], - ], - $checks - ); - $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint'); - if (!$checks['gpg']['gpgHome'] || $fingerprint === null) { - return $checks; - } - $gpg = OpenPGPBackendFactory::get(); - if (!$gpg->isKeyInKeyring($fingerprint)) { - return $checks; - } - $checks['gpg']['gpgKeyPublicInKeyring'] = true; - - return $checks; - } - - /** - * Check if it can encrypt - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpgCanEncrypt(?array $checks = []): array - { - $checks = array_replace_recursive( - [ - 'gpg' => [ - 'canEncrypt' => false, - 'gpgKeyPublicInKeyring' => false, - ], - ], - $checks - ); - if ($checks['gpg']['gpgKeyPublicInKeyring']) { - $_gpg = OpenPGPBackendFactory::get(); - $messageToEncrypt = 'test message'; - try { - $_gpg->setEncryptKeyFromFingerprint(Configure::read('passbolt.gpg.serverKey.fingerprint')); - $_gpg->encrypt($messageToEncrypt); - $checks['gpg']['canEncrypt'] = true; - } catch (CakeException $e) { - $checks['gpg']['canEncrypt'] = false; - } - } - - return $checks; - } - - /** - * Check if it can encrypt and sign - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpgCanEncryptSign(?array $checks = []): array - { - $checks = array_replace_recursive( - [ - 'gpg' => [ - 'canEncryptSign' => false, - 'gpgKeyPublicInKeyring' => false, - ], - ], - $checks - ); - if ($checks['gpg']['gpgKeyPublicInKeyring']) { - $_gpg = OpenPGPBackendFactory::get(); - $messageToEncrypt = 'test message'; - try { - $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint'); - $passphrase = Configure::read('passbolt.gpg.serverKey.passphrase'); - $_gpg->setEncryptKeyFromFingerprint($fingerprint); - $_gpg->setSignKeyFromFingerprint($fingerprint, $passphrase); - $_gpg->encrypt($messageToEncrypt, true); - $checks['gpg']['canEncryptSign'] = true; - } catch (CakeException $e) { - $checks['gpg']['canEncryptSign'] = false; - } - } - - return $checks; - } - - /** - * Check if it can decrypt - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpgCanDecrypt(?array $checks = []): array - { - $checks = array_replace_recursive( - [ - 'gpg' => [ - 'canEncrypt' => false, - 'canDecrypt' => false, - 'gpgKeyPublicInKeyring' => false, - ], - ], - $checks - ); - if ($checks['gpg']['gpgKeyPublicInKeyring']) { - if ($checks['gpg']['canEncrypt']) { - $_gpg = OpenPGPBackendFactory::get(); - $messageToEncrypt = 'test message'; - try { - $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint'); - $passphrase = Configure::read('passbolt.gpg.serverKey.passphrase'); - $_gpg->setEncryptKeyFromFingerprint($fingerprint); - $encryptedMessage = $_gpg->encrypt($messageToEncrypt); - $_gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase); - $decryptedMessage = $_gpg->decrypt($encryptedMessage); - if ($decryptedMessage === $messageToEncrypt) { - $checks['gpg']['canDecrypt'] = true; - } - } catch (CakeException $e) { - } - } - } - - return $checks; - } - - /** - * Check if it can decrypt and verify signature - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpgCanDecryptVerify(?array $checks = []): array - { - $checks = array_replace_recursive( - [ - 'gpg' => [ - 'canDecryptVerify' => false, - 'gpgKeyPublicInKeyring' => false, - ], - ], - $checks - ); - if ($checks['gpg']['gpgKeyPublicInKeyring']) { - $_gpg = OpenPGPBackendFactory::get(); - $messageToEncrypt = 'test message'; - try { - $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint'); - $passphrase = Configure::read('passbolt.gpg.serverKey.passphrase'); - $_gpg->setEncryptKeyFromFingerprint($fingerprint); - $_gpg->setSignKeyFromFingerprint($fingerprint, $passphrase); - $encryptedMessage2 = $_gpg->encrypt($messageToEncrypt, true); - $_gpg->setVerifyKeyFromFingerprint($fingerprint); - $_gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase); - $decryptedMessage2 = $_gpg->decrypt($encryptedMessage2, true); - if ($decryptedMessage2 === $messageToEncrypt) { - $checks['gpg']['canDecryptVerify'] = true; - } - } catch (CakeException $e) { - } - } - - return $checks; - } - - /** - * Check if it can verify - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpgCanSign(?array $checks = []): array - { - $checks = array_replace_recursive( - [ - 'gpg' => [ - 'gpgKeyPublicInKeyring' => false, - 'canSign' => false, - ], - ], - $checks - ); - if ($checks['gpg']['gpgKeyPublicInKeyring']) { - $_gpg = OpenPGPBackendFactory::get(); - $_gpg->setSignKeyFromFingerprint( - Configure::read('passbolt.gpg.serverKey.fingerprint'), - Configure::read('passbolt.gpg.serverKey.passphrase') - ); - $messageToEncrypt = 'test message'; - try { - $_gpg->sign($messageToEncrypt); - $checks['gpg']['canSign'] = true; - } catch (CakeException $e) { - $checks['gpg']['canSign'] = false; - } - } - - return $checks; - } - - /** - * Check if it can verify - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpgCanVerify(?array $checks = []): array - { - $checks = array_replace_recursive( - [ - 'gpg' => [ - 'canDecryptVerify' => false, - 'canVerify' => false, - ], - ], - $checks - ); - if ($checks['gpg']['canDecryptVerify']) { - $_gpg = OpenPGPBackendFactory::get(); - $messageToEncrypt = 'test message'; - - try { - $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint'); - $passphrase = Configure::read('passbolt.gpg.serverKey.passphrase'); - $_gpg->setSignKeyFromFingerprint($fingerprint, $passphrase); - $signedMessage = $_gpg->sign($messageToEncrypt); - - try { - $_gpg->setVerifyKeyFromFingerprint($fingerprint); - $_gpg->verify($signedMessage); - $checks['gpg']['canVerify'] = true; - } catch (CakeException $e) { - } - } catch (CakeException $e) { - } - } - - return $checks; - } - - /** - * Check if both server keys are Gopengpg readable. - * There should for example be no empty line before the end of - * the block. - * - * @param array|null $checks List of checks - * @return array - */ - public static function gpgIsFormatGopengpgValid(?array $checks = []): array - { - // Gpg keys should have only one return line - $publicKey = new Gpgkey(); - $publicKey->armored_key = file_get_contents(Configure::read('passbolt.gpg.serverKey.public')); - $privateKey = new Gpgkey(); - $privateKey->armored_key = file_get_contents(Configure::read('passbolt.gpg.serverKey.private')); - $rule = new GopengpgFormatRule(); - $checks['gpg']['isPublicServerKeyGopengpgCompatible'] = $rule($publicKey); - $checks['gpg']['isPrivateServerKeyGopengpgCompatible'] = $rule($privateKey); - - return $checks; - } -} diff --git a/src/Utility/Healthchecks/SslHealthchecks.php b/src/Utility/Healthchecks/SslHealthchecks.php deleted file mode 100644 index 07a5524662..0000000000 --- a/src/Utility/Healthchecks/SslHealthchecks.php +++ /dev/null @@ -1,133 +0,0 @@ -client = $client; - } - - /** - * Run all SSL healthchecks - * - * @param array|null $checks List of checks - * @return array - */ - public function all(?array $checks = []): array - { - $checks['ssl'] = [ - 'peerValid' => false, - 'hostValid' => false, - 'notSelfSigned' => false, - ]; - // No point to check anything if this Core config is not valid - if (isset($checks['core']['fullBaseUrlReachable'])) { - $reachable = $checks['core']['fullBaseUrlReachable']; - } - if (isset($reachable) && !$reachable) { - return $checks; - } - $checks = $this->peerValid($checks); - $checks = $this->hostValid($checks); - $checks = $this->notSelfSigned($checks); - - return $checks; - } - - /** - * Check if peer is valid - * - * @param array|null $checks List of checks - * @return array - */ - private function peerValid(?array $checks = []): array - { - $url = Router::url('/healthcheck/status.json', true); - try { - $HttpSocket = $this->client ?? new Client([ - 'ssl_verify_peer' => true, - 'ssl_verify_host' => false, - 'ssl_allow_self_signed' => true, - ]); - $response = $HttpSocket->get($url); - $checks['ssl']['peerValid'] = $response->isOk(); - } catch (\Exception $e) { - $checks['ssl']['info'] = $e->getMessage(); - } - - return $checks; - } - - /** - * Check if the host is valid - * - * @param array|null $checks List of checks - * @return array - */ - private function hostValid(?array $checks = []): array - { - $url = Router::url('/healthcheck/status.json', true); - try { - $HttpSocket = $this->client ?? new Client([ - 'ssl_verify_peer' => true, - 'ssl_verify_host' => true, - 'ssl_allow_self_signed' => true, - ]); - $response = $HttpSocket->get($url); - $checks['ssl']['hostValid'] = $response->isOk(); - } catch (\Exception $e) { - $checks['ssl']['info'] = $e->getMessage(); - } - - return $checks; - } - - /** - * Check that the certificate is not self signed - * - * @param array|null $checks List of checks - * @psalm-suppress InvalidNullableReturnType false positive - * @return array - */ - private function notSelfSigned(?array $checks = []): array - { - $url = Router::url('/healthcheck/status.json', true); - try { - $HttpSocket = $this->client ?? new Client([ - 'ssl_verify_peer' => true, - 'ssl_verify_host' => true, - 'ssl_allow_self_signed' => false, - ]); - $response = $HttpSocket->get($url); - $checks['ssl']['notSelfSigned'] = $response->isOk(); - } catch (\Exception $e) { - } - - /** @psalm-suppress NullableReturnStatement false positive */ - return $checks; - } -} diff --git a/src/Utility/Migration.php b/src/Utility/Migration.php deleted file mode 100644 index 9612a09072..0000000000 --- a/src/Utility/Migration.php +++ /dev/null @@ -1,85 +0,0 @@ - ConnectionManager::get('default')->configName()]); - $migrations = $Migrations->status(); - foreach ($migrations as $i => $migration) { - if ($migration['status'] === 'down') { - return true; - } - } - - return false; - } - - /** - * Return true if the current installed version match the latest official one - * - * @return bool true if installed version is the latest - */ - public static function isLatestVersion() - { - $remoteVersion = ltrim(Migration::getLatestTagName(), 'v'); - $localVersion = ltrim(Configure::read('passbolt.version'), 'v'); - - return version_compare($localVersion, $remoteVersion, '>='); - } - - /** - * Return the current master version according to the official passbolt repository - * - * @throws \Exception if the github repository is not reachable - * @throws \Exception if the tag information cannot be retrieved - * @return string tag name such as 'v1.0.1' - */ - public static function getLatestTagName(): string - { - $remoteTagName = Configure::read('passbolt.remote.version'); - if (is_null($remoteTagName)) { - $url = 'https://api.github.com/repos/passbolt/passbolt_api/releases/latest'; - try { - $HttpSocket = new Client(); - $results = $HttpSocket->get($url); - } catch (\Exception $e) { - throw new \Exception(__('Could not connect to github repository')); - } - $tags = json_decode($results->getStringBody(), true); - if (!isset($tags['tag_name'])) { - throw new \Exception(__('Could not read tag information on github repository')); - } - $remoteTagName = ltrim($tags['tag_name'], 'v'); - Configure::write('passbolt.remote.version', $remoteTagName); - } - - return $remoteTagName; - } -} diff --git a/templates/Healthcheck/index.php b/templates/Healthcheck/index.php index e608a6c7b1..b187d11068 100644 --- a/templates/Healthcheck/index.php +++ b/templates/Healthcheck/index.php @@ -11,7 +11,10 @@ * @license https://opensource.org/licenses/AGPL-3.0 AGPL License * @link https://www.passbolt.com Passbolt(tm) * @since 2.0.0 + * + * @var array $body */ + use App\View\Helper\HealthcheckHtmlHelper; use Cake\Core\Configure; @@ -19,7 +22,7 @@ $this->Html->css('themes/default/api_main.min.css?v=' . Configure::read('passbolt.version'), ['block' => 'css', 'fullBase' => true]); $this->assign('pageClass', 'status'); -$healthcheck = new HealthcheckHtmlHelper(); +$healthcheckHelper = new HealthcheckHtmlHelper(); ?>
@@ -27,27 +30,19 @@

assertEnvironment($body); + foreach ($body as $domain => $checkResults) { + echo '

' . $domain . '

'; + + foreach ($checkResults as $checkResult) { + $healthcheckHelper->render($checkResult); + } + } ?> - ' . __('SSL access is enabled.') . '
'; - else: - echo '
' . __('SSL access is not enabled.') . '
'; - endif; - ?> - assertConfigFiles($body); - $healthcheck->assertCore($body); - $healthcheck->assertDatabase($body); - $healthcheck->assertGpg($body); - $healthcheck->assertApplication($body); - ?>