├── .DS_Store ├── .gitignore ├── assets ├── .DS_Store ├── css │ ├── .DS_Store │ ├── admin.css │ ├── admin.css.map │ ├── admin.min.css │ ├── admin.scss │ ├── admin │ │ ├── base.scss │ │ ├── index.php │ │ ├── layout.scss │ │ ├── modules │ │ │ ├── animations.scss │ │ │ ├── badges.scss │ │ │ ├── bullets.scss │ │ │ ├── buttons.scss │ │ │ ├── dashboard.scss │ │ │ ├── datatables.scss │ │ │ ├── header.scss │ │ │ ├── icons.scss │ │ │ ├── introcontainer.scss │ │ │ ├── modal.scss │ │ │ ├── new-features.scss │ │ │ ├── notices.scss │ │ │ ├── onboarding.scss │ │ │ ├── other-plugins.scss │ │ │ ├── placeholder.scss │ │ │ ├── premium_overlay.scss │ │ │ ├── progress.scss │ │ │ ├── ssltest.scss │ │ │ ├── tips-tricks.scss │ │ │ ├── toast │ │ │ │ ├── _closeButton.scss │ │ │ │ ├── _icons.scss │ │ │ │ ├── _progressBar.scss │ │ │ │ ├── _theme.scss │ │ │ │ ├── _toast.scss │ │ │ │ ├── _toastContainer.scss │ │ │ │ ├── _variables.scss │ │ │ │ ├── animations │ │ │ │ │ ├── _bounce.scss │ │ │ │ │ ├── _flip.scss │ │ │ │ │ ├── _slide.scss │ │ │ │ │ ├── _spin.scss │ │ │ │ │ └── _zoom.scss │ │ │ │ ├── main.scss │ │ │ │ └── minimal.scss │ │ │ ├── tooltip.scss │ │ │ ├── two-fa.scss │ │ │ ├── wizard.scss │ │ │ ├── wizard │ │ │ │ ├── fields.scss │ │ │ │ ├── learning-mode.scss │ │ │ │ ├── letsencrypt.scss │ │ │ │ ├── menu.scss │ │ │ │ ├── mixed-content-scan.scss │ │ │ │ ├── notice.scss │ │ │ │ ├── permissions-policy.scss │ │ │ │ ├── snackbar.scss │ │ │ │ └── vulnerabilities.scss │ │ │ └── xml-rpc.scss │ │ ├── states.scss │ │ └── theme.scss │ ├── index.php │ ├── rsssl-plugin.css │ ├── rsssl-plugin.min.css │ ├── rsssl-plugin.scss │ ├── rtl │ │ ├── admin.min.css │ │ ├── plugin.min.css │ │ └── rsssl-plugin.min.css │ └── variables.scss ├── features │ └── two-fa │ │ ├── assets.min.asset.php │ │ ├── assets.min.js │ │ ├── assets.min.js.map │ │ ├── styles-rtl.css │ │ ├── styles.css │ │ ├── styles.css.map │ │ ├── styles.min.asset.php │ │ ├── styles.min.js │ │ └── styles.min.js.map ├── img │ ├── .DS_Store │ ├── icon.png │ ├── index.php │ ├── really-simple-plugins.svg │ └── really-simple-security-logo.svg ├── index.php ├── js │ └── .DS_Store └── templates │ ├── passkey │ └── login.php │ └── two_fa │ ├── expired.php │ ├── login.php │ ├── onboarding.php │ ├── profile-settings.php │ ├── selectable-option.php │ └── totp-config.php ├── class-admin.php ├── class-cache.php ├── class-certificate.php ├── class-front-end.php ├── class-installer.php ├── class-mixed-content-fixer.php ├── class-multisite.php ├── class-server.php ├── class-site-health.php ├── class-wp-cli.php ├── compatibility.php ├── force-deactivate.txt ├── functions.php ├── index.php ├── languages ├── index.php ├── really-simple-ssl-nl_NL.l10n.php └── really-simple-ssl.pot ├── lets-encrypt ├── class-le-restapi.php ├── class-letsencrypt-handler.php ├── composer.json ├── composer.lock ├── composer.phar ├── config │ ├── class-hosts.php │ ├── fields.php │ ├── index.php │ └── notices.php ├── cron.php ├── download.php ├── functions.php ├── index.php ├── integrations │ ├── cloudways │ │ ├── cloudways.php │ │ └── functions.php │ ├── cpanel │ │ ├── cpanel.php │ │ └── functions.php │ ├── directadmin │ │ ├── directadmin.php │ │ ├── functions.php │ │ └── httpsocket.php │ ├── hostgator │ │ └── hostgator.php │ ├── index.php │ ├── integrations.php │ └── plesk │ │ ├── functions.php │ │ └── plesk.php ├── letsencrypt.php ├── node_modules │ ├── composer │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── generator.js │ │ │ ├── parse.js │ │ │ ├── task.js │ │ │ ├── tasks.js │ │ │ ├── timer.js │ │ │ └── utils.js │ │ └── package.json │ ├── pretty-time │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── utils.js │ └── use │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ └── package.json ├── package-lock.json └── vendor │ ├── autoload.php │ ├── composer │ ├── ClassLoader.php │ ├── InstalledVersions.php │ ├── LICENSE │ ├── autoload_classmap.php │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── autoload_real.php │ ├── autoload_static.php │ ├── index.php │ ├── installed.json │ ├── installed.php │ └── platform_check.php │ ├── fbett │ ├── index.php │ └── le_acme2 │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── composer.json │ │ ├── phpunit.xml.dist │ │ └── src │ │ ├── LE_ACME2 │ │ ├── AbstractKeyValuable.php │ │ ├── Account.php │ │ ├── Authorizer │ │ │ ├── AbstractAuthorizer.php │ │ │ ├── AbstractDNSWriter.php │ │ │ ├── DNS.php │ │ │ └── HTTP.php │ │ ├── Cache │ │ │ ├── AbstractKeyValuableCache.php │ │ │ ├── AccountResponse.php │ │ │ ├── DirectoryResponse.php │ │ │ ├── NewNonceResponse.php │ │ │ └── OrderResponse.php │ │ ├── Connector │ │ │ ├── Connector.php │ │ │ └── RawResponse.php │ │ ├── Exception │ │ │ ├── AbstractException.php │ │ │ ├── AuthorizationInvalid.php │ │ │ ├── DNSAuthorizationInvalid.php │ │ │ ├── ExpiredAuthorization.php │ │ │ ├── HTTPAuthorizationInvalid.php │ │ │ ├── InvalidResponse.php │ │ │ ├── OpenSSLException.php │ │ │ ├── RateLimitReached.php │ │ │ └── StatusInvalid.php │ │ ├── Order.php │ │ ├── Request │ │ │ ├── AbstractRequest.php │ │ │ ├── Account │ │ │ │ ├── AbstractLocation.php │ │ │ │ ├── ChangeKeys.php │ │ │ │ ├── Create.php │ │ │ │ ├── Deactivate.php │ │ │ │ ├── Get.php │ │ │ │ ├── GetData.php │ │ │ │ └── Update.php │ │ │ ├── Authorization │ │ │ │ ├── Get.php │ │ │ │ └── Start.php │ │ │ ├── GetDirectory.php │ │ │ ├── GetNewNonce.php │ │ │ └── Order │ │ │ │ ├── Create.php │ │ │ │ ├── Finalize.php │ │ │ │ ├── Get.php │ │ │ │ ├── GetCertificate.php │ │ │ │ └── RevokeCertificate.php │ │ ├── Response │ │ │ ├── AbstractResponse.php │ │ │ ├── Account │ │ │ │ ├── AbstractAccount.php │ │ │ │ ├── AbstractLocation.php │ │ │ │ ├── ChangeKeys.php │ │ │ │ ├── Create.php │ │ │ │ ├── Deactivate.php │ │ │ │ ├── Get.php │ │ │ │ ├── GetData.php │ │ │ │ └── Update.php │ │ │ ├── Authorization │ │ │ │ ├── AbstractAuthorization.php │ │ │ │ ├── Get.php │ │ │ │ ├── Start.php │ │ │ │ └── Struct │ │ │ │ │ ├── Challenge.php │ │ │ │ │ └── Identifier.php │ │ │ ├── GetDirectory.php │ │ │ ├── GetNewNonce.php │ │ │ └── Order │ │ │ │ ├── AbstractOrder.php │ │ │ │ ├── Create.php │ │ │ │ ├── Finalize.php │ │ │ │ ├── Get.php │ │ │ │ ├── GetCertificate.php │ │ │ │ └── RevokeCertificate.php │ │ ├── SingletonTrait.php │ │ ├── Struct │ │ │ ├── CertificateBundle.php │ │ │ └── ChallengeAuthorizationKey.php │ │ └── Utilities │ │ │ ├── Base64.php │ │ │ ├── Certificate.php │ │ │ ├── KeyGenerator.php │ │ │ ├── Logger.php │ │ │ └── RequestSigner.php │ │ └── LE_ACME2Tests │ │ ├── AbstractTest.php │ │ ├── AccountTest.php │ │ ├── Authorizer │ │ └── HTTPTest.php │ │ └── TestHelper.php │ ├── index.php │ └── plesk │ ├── api-php-lib │ ├── .styleci.yml │ ├── .travis.yml │ ├── Dockerfile │ ├── LICENSE │ ├── README.md │ ├── composer.json │ ├── composer.lock │ ├── docker-compose.yml │ ├── phpunit-watcher.yml │ ├── phpunit.xml.dist │ ├── src │ │ └── Api │ │ │ ├── Client.php │ │ │ ├── Client │ │ │ └── Exception.php │ │ │ ├── Exception.php │ │ │ ├── InternalClient.php │ │ │ ├── Operator.php │ │ │ ├── Operator │ │ │ ├── Certificate.php │ │ │ ├── Dns.php │ │ │ ├── EventLog.php │ │ │ ├── Ip.php │ │ │ ├── Locale.php │ │ │ ├── PhpHandler.php │ │ │ ├── ProtectedDirectory.php │ │ │ ├── SecretKey.php │ │ │ ├── Server.php │ │ │ ├── Session.php │ │ │ └── SiteAlias.php │ │ │ ├── Struct.php │ │ │ ├── Struct │ │ │ ├── Certificate │ │ │ │ └── Info.php │ │ │ ├── Dns │ │ │ │ └── Info.php │ │ │ ├── EventLog │ │ │ │ ├── DetailedEvent.php │ │ │ │ └── Event.php │ │ │ ├── Locale │ │ │ │ └── Info.php │ │ │ ├── PhpHandler │ │ │ │ └── Info.php │ │ │ ├── SecretKey │ │ │ │ └── Info.php │ │ │ ├── Session │ │ │ │ └── Info.php │ │ │ ├── Site │ │ │ │ ├── GeneralInfo.php │ │ │ │ ├── HostingInfo.php │ │ │ │ └── Info.php │ │ │ └── SiteAlias │ │ │ │ ├── GeneralInfo.php │ │ │ │ └── Info.php │ │ │ └── XmlResponse.php │ └── wait-for-plesk.sh │ └── index.php ├── lib └── admin │ ├── class-encryption.php │ └── class-helper.php ├── mailer ├── .DS_Store ├── class-mail-admin.php ├── class-mail.php ├── index.php └── templates │ ├── block-unbranded.html │ ├── block.html │ ├── email-unbranded.html │ ├── email.html │ └── index.php ├── modal ├── .DS_Store ├── build │ ├── 291.61c1eeb0cf491fffa001.js │ ├── 433.css │ ├── 433.ef6236b038b45328e4c7.js │ ├── 926.f073f8b70413c27b4a27.js │ ├── index.d4bca8705bbc6e3e5777.asset.php │ └── index.d4bca8705bbc6e3e5777.js ├── modal.php ├── package-lock.json ├── package.json ├── src │ ├── components │ │ ├── DeactivationModal │ │ │ └── DeactivationModal.js │ │ └── Modal │ │ │ ├── RssslModal.js │ │ │ └── RssslModal.scss │ └── index.js └── webpack.config.js ├── onboarding ├── class-onboarding.php └── index.php ├── placeholders ├── class-placeholder.php └── index.php ├── progress ├── class-progress.php └── index.php ├── readme.txt ├── rector.php ├── rlrsssl-really-simple-ssl.php ├── rsssl-auto-loader.php ├── security.md ├── security ├── cron.php ├── deactivate-integration.php ├── firewall-manager.php ├── functions.php ├── hardening.php ├── includes │ └── check404 │ │ ├── class-rsssl-simple-404-interceptor.php │ │ └── class-rsssl-test-404.php ├── index.php ├── integrations.php ├── notices.php ├── security.php ├── server │ ├── disable-indexing.php │ └── index.php ├── sync-settings.php ├── tests.php ├── tests │ ├── code-execution.php │ └── index.php └── wordpress │ ├── block-code-execution-uploads.php │ ├── disable-xmlrpc.php │ ├── display-name-is-login-name.php │ ├── file-editing.php │ ├── hide-wp-version.php │ ├── index.php │ ├── prevent-login-info-leakage.php │ ├── rename-admin-user.php │ ├── rest-api.php │ ├── two-fa │ ├── assets │ │ ├── css │ │ │ ├── profile-settings.scss │ │ │ ├── two-fa-onboarding.scss │ │ │ └── two-fa.scss │ │ └── js │ │ │ ├── BaseAuth.js │ │ │ ├── initialize_two_fa.js │ │ │ ├── onboarding.js │ │ │ └── profile.js │ ├── class-rsssl-parameter-validation.php │ ├── class-rsssl-passkey-list-table.php │ ├── class-rsssl-two-fa-authentication.php │ ├── class-rsssl-two-fa-data-parameters.php │ ├── class-rsssl-two-fa-status.php │ ├── class-rsssl-two-factor-admin.php │ ├── class-rsssl-two-factor-compat.php │ ├── class-rsssl-two-factor-on-board-api.php │ ├── class-rsssl-two-factor-profile-settings.php │ ├── class-rsssl-two-factor-reset-factory.php │ ├── class-rsssl-two-factor-settings.php │ ├── class-rsssl-two-factor.php │ ├── contracts │ │ ├── interface-rsssl-has-processing-interface.php │ │ ├── interface-rsssl-two-fa-user-query-builder-interface.php │ │ └── interface-rsssl-two-fa-user-repository-interface.php │ ├── controllers │ │ ├── class-rsssl-abstract-controller.php │ │ ├── class-rsssl-base-controller.php │ │ ├── class-rsssl-email-controller.php │ │ └── class-rsssl-two-fa-user-controller.php │ ├── function-login-footer.php │ ├── function-login-header.php │ ├── models │ │ ├── class-rsssl-request-parameters.php │ │ ├── class-rsssl-two-fa-data-parameters.php │ │ ├── class-rsssl-two-fa-user-collection.php │ │ ├── class-rsssl-two-fa-user.php │ │ └── class-rsssl-two-factor-user-factory.php │ ├── providers │ │ ├── class-rsssl-provider-loader-free.php │ │ ├── class-rsssl-provider-loader.php │ │ ├── class-rsssl-two-factor-email.php │ │ ├── class-rsssl-two-factor-provider.php │ │ └── interface-rsssl-two-factor-provider-interface.php │ ├── repositories │ │ ├── class-rsssl-two-fa-user-query-builder.php │ │ └── class-rsssl-two-fa-user-repository.php │ ├── services │ │ ├── class-rsssl-callback-queue.php │ │ ├── class-rsssl-two-fa-forced-role-service.php │ │ ├── class-rsssl-two-fa-reminder-service.php │ │ ├── class-rsssl-two-fa-status-service.php │ │ └── class-rsssl-two-factor-reset-service.php │ └── traits │ │ ├── trait-rsssl-args-builder.php │ │ ├── trait-rsssl-email-trait.php │ │ └── trait-rsssl-two-fa-helper.php │ ├── user-enumeration.php │ ├── user-registration.php │ ├── vulnerabilities.php │ └── vulnerabilities │ ├── FileStorage.php │ ├── class-rsssl-file-storage.php │ └── class-rsssl-folder-name.php ├── settings ├── build │ ├── 139.12de12bd599af6bb648c.js │ ├── 366.79830113ad25eba9fb57.js │ ├── 470.5091a8eb35ca6d3dbc61.js │ ├── 485-rtl.css │ ├── 485.47f7474dc2a61c04262b.js │ ├── 485.css │ ├── 573.287bf1828cad7f912345.js │ ├── 8.a58b0fbbca98fed315b4.js │ ├── 829-rtl.css │ ├── 829.0d69f68a1345874307b1.js │ ├── 829.css │ ├── 838.c841004b517cdf3abd86.js │ ├── 91.b0f863c7b47144cb4cdf.js │ ├── 995.7a0675fe0519b06656b3.js │ ├── index.a4cc556db77e3384994b.asset.php │ └── index.a4cc556db77e3384994b.js ├── config │ ├── config.php │ ├── disable-fields-filter.php │ ├── fields │ │ ├── access-control.php │ │ ├── encryption.php │ │ ├── firewall.php │ │ ├── general.php │ │ ├── hardening-basic.php │ │ ├── hardening-extended.php │ │ ├── hardening-xml.php │ │ ├── hibp-integration.php │ │ ├── letsencrypt.php │ │ ├── limit-login-attempts.php │ │ ├── security-headers.php │ │ ├── two-fa.php │ │ └── vulnerability-detection.php │ ├── index.php │ ├── mails.php │ └── menu.php ├── dist │ ├── bundle.js │ └── main.min.css ├── index.php ├── package-lock.json ├── package.json ├── settings.php ├── src │ ├── Dashboard │ │ ├── DashboardPage.js │ │ ├── GridBlock.js │ │ ├── OtherPlugins │ │ │ ├── OtherPlugins.js │ │ │ ├── OtherPluginsData.js │ │ │ └── OtherPluginsHeader.js │ │ ├── Progress │ │ │ ├── ProgressBlock.js │ │ │ ├── ProgressBlockHeader.js │ │ │ ├── ProgressData.js │ │ │ └── ProgressFooter.js │ │ ├── SslLabs │ │ │ ├── SslLabs.js │ │ │ ├── SslLabsData.js │ │ │ ├── SslLabsFooter.js │ │ │ └── SslLabsHeader.js │ │ ├── TaskElement.js │ │ ├── TipsTricks │ │ │ ├── TipsTricks.js │ │ │ └── TipsTricksFooter.js │ │ └── Vulnerabilities │ │ │ ├── Vulnerabilities.js │ │ │ ├── VulnerabilitiesFooter.js │ │ │ └── VulnerabilitiesHeader.js │ ├── Header.js │ ├── LetsEncrypt │ │ ├── Activate.js │ │ ├── Directories.js │ │ ├── DnsVerification.js │ │ ├── Generation.js │ │ ├── Installation.js │ │ ├── LetsEncrypt.js │ │ └── letsEncryptData.js │ ├── Menu │ │ ├── Menu.js │ │ ├── MenuData.js │ │ └── MenuItem.js │ ├── Modal │ │ ├── Modal.js │ │ ├── ModalControl.js │ │ └── ModalData.js │ ├── Onboarding │ │ ├── Items │ │ │ ├── CheckboxItem.js │ │ │ ├── ListItem.js │ │ │ └── PremiumItem.js │ │ ├── Onboarding.js │ │ ├── OnboardingControls.js │ │ ├── OnboardingData.js │ │ ├── OnboardingModal.js │ │ ├── PremiumItem.scss │ │ ├── Steps │ │ │ ├── StepConfig.js │ │ │ ├── StepEmail.js │ │ │ ├── StepFeatures.js │ │ │ ├── StepLicense.js │ │ │ ├── StepPlugins.js │ │ │ └── StepPro.js │ │ ├── checkbox.scss │ │ └── onboarding.scss │ ├── Page.js │ ├── Placeholder │ │ ├── DashboardPlaceholder.js │ │ ├── DatatablePlaceholder.js │ │ ├── MenuPlaceholder.js │ │ ├── PagePlaceholder.js │ │ ├── Placeholder.js │ │ └── SettingsPlaceholder.js │ ├── Settings │ │ ├── AutoComplete │ │ │ ├── AutoComplete.scss │ │ │ └── AutoCompleteControl.js │ │ ├── Button.js │ │ ├── Captcha │ │ │ ├── Captcha.js │ │ │ ├── CaptchaData.js │ │ │ ├── CaptchaKey.js │ │ │ ├── HCaptcha.js │ │ │ └── ReCaptcha.js │ │ ├── CheckboxControl.js │ │ ├── DataTable │ │ │ ├── Buttons │ │ │ │ ├── Buttons.scss │ │ │ │ ├── ControlButton.js │ │ │ │ ├── MultiSelectButton.js │ │ │ │ └── RowButton.js │ │ │ ├── Checkboxes.scss │ │ │ ├── DataTable.scss │ │ │ ├── DataTableStore.js │ │ │ ├── DataTableWrapper.js │ │ │ ├── SearchBar │ │ │ │ ├── SearchBar.js │ │ │ │ └── SearchBar.scss │ │ │ └── SelectedRowsControl │ │ │ │ ├── SelectedRowsControl.js │ │ │ │ └── SelectedRowsControl.scss │ │ ├── DynamicDataTable │ │ │ ├── AddButton.js │ │ │ ├── DynamicDataTable.js │ │ │ ├── DynamicDataTableStore.js │ │ │ └── SearchBar.js │ │ ├── EventLog │ │ │ ├── EventLogDataTable.js │ │ │ └── EventLogDataTableStore.js │ │ ├── Field.js │ │ ├── FieldsData.js │ │ ├── FilterData.js │ │ ├── GeoBlockList │ │ │ ├── AddButton.js │ │ │ ├── BlockListDatatable.js │ │ │ ├── GeoDataTableStore.js │ │ │ ├── GeoDatatable.js │ │ │ ├── TrustIpAddressModal.js │ │ │ ├── WhiteListDatatable.js │ │ │ └── WhiteListTableStore.js │ │ ├── GroupFilter.js │ │ ├── Help.js │ │ ├── Host │ │ │ ├── Host.js │ │ │ └── HostData.js │ │ ├── LearningMode │ │ │ ├── ChangeStatus.js │ │ │ ├── Delete.js │ │ │ ├── LearningMode.js │ │ │ ├── LearningModeData.js │ │ │ ├── ManualCspAddition.js │ │ │ └── ManualCspAdditionModal.js │ │ ├── License │ │ │ ├── License.js │ │ │ └── LicenseData.js │ │ ├── LimitLoginAttempts │ │ │ ├── AddIpAddressModal.js │ │ │ ├── AddUserModal.js │ │ │ ├── Cidr.js │ │ │ ├── CountryDataTableStore.js │ │ │ ├── CountryDatatable.js │ │ │ ├── IpAddressDataTableStore.js │ │ │ ├── IpAddressDatatable.js │ │ │ ├── IpAddressInput.js │ │ │ ├── LimitLoginAttemptsData.js │ │ │ ├── UserDataTableStore.js │ │ │ └── UserDatatable.js │ │ ├── MixedContentScan │ │ │ ├── MixedContentData.js │ │ │ └── MixedContentScan.js │ │ ├── Notices.js │ │ ├── Password.js │ │ ├── PermissionsPolicy.js │ │ ├── PostDropDown.js │ │ ├── PremiumOverlay.js │ │ ├── RiskConfiguration │ │ │ ├── NotificationTester.js │ │ │ ├── RiskComponent.js │ │ │ ├── RiskData.js │ │ │ ├── RunnerData.js │ │ │ ├── VulnerabilitiesOverview.js │ │ │ ├── datatable.scss │ │ │ └── modal.scss │ │ ├── RolesDropDown.js │ │ ├── SelectControl.js │ │ ├── Settings.js │ │ ├── SettingsGroup.js │ │ ├── Support.js │ │ ├── TwoFA │ │ │ ├── RolesStore.js │ │ │ ├── TwoFaDataTable.js │ │ │ ├── TwoFaDataTableStore.js │ │ │ ├── TwoFaEnabledDropDown.js │ │ │ ├── TwoFaRolesDropDown.js │ │ │ └── select.scss │ │ └── firewall │ │ │ ├── UserAgentModal.js │ │ │ ├── UserAgentStore.js │ │ │ └── UserAgentTable.js │ ├── index.js │ ├── index.php │ └── utils │ │ ├── AddUrlRef.js │ │ ├── Error.js │ │ ├── ErrorBoundary.js │ │ ├── Flag │ │ └── Flag.js │ │ ├── Hyperlink.js │ │ ├── Icon.js │ │ ├── ReactConditions.js │ │ ├── api.js │ │ ├── autoCompleteTheme.js │ │ ├── formatting.js │ │ ├── getAnchor.js │ │ ├── hoverTooltip.js │ │ ├── hoverTooltip_bu.js │ │ ├── lib.js │ │ └── sleeper.js ├── webpack.config.js └── webpack.feature.config.js ├── ssl-test-page.php ├── system-status.php ├── testssl ├── cloudflare │ ├── .htaccess │ └── ssl-test-page.html ├── cloudfront │ ├── .htaccess │ └── ssl-test-page.html ├── envhttps │ ├── .htaccess │ └── ssl-test-page.html ├── loadbalancer │ ├── .htaccess │ └── ssl-test-page.html ├── serverhttps1 │ ├── .htaccess │ └── ssl-test-page.html ├── serverhttpson │ ├── .htaccess │ └── ssl-test-page.html ├── serverhttpxforwardedssl1 │ ├── .htaccess │ └── ssl-test-page.html ├── serverhttpxforwardedsslon │ ├── .htaccess │ └── ssl-test-page.html ├── serverhttpxproto │ ├── .htaccess │ └── ssl-test-page.html └── serverport443 │ ├── .htaccess │ └── ssl-test-page.html ├── uninstall.php ├── upgrade.php └── upgrade ├── ajax.js ├── ajax.min.js ├── img ├── burst.png ├── complianz-gdpr.png └── really-simple-ssl.png ├── index.php ├── upgrade-to-pro.css ├── upgrade-to-pro.css.map ├── upgrade-to-pro.js ├── upgrade-to-pro.less ├── upgrade-to-pro.min.css ├── upgrade-to-pro.min.js └── upgrade-to-pro.php /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | prepros.config 2 | settings/node_modules/* 3 | modal/node_modules/* 4 | node_modules/* 5 | .idea 6 | vendor/ 7 | -------------------------------------------------------------------------------- /assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/.DS_Store -------------------------------------------------------------------------------- /assets/css/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/.DS_Store -------------------------------------------------------------------------------- /assets/css/admin/base.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/admin/base.scss -------------------------------------------------------------------------------- /assets/css/admin/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/admin/index.php -------------------------------------------------------------------------------- /assets/css/admin/layout.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/admin/layout.scss -------------------------------------------------------------------------------- /assets/css/admin/modules/animations.scss: -------------------------------------------------------------------------------- 1 | /* Accordeon */ 2 | 3 | .rsssl-accordeon { 4 | /* Basic styling for the accordion container */ 5 | border: 1px solid #ccc; 6 | border-radius: 5px; 7 | overflow: hidden; 8 | transition: all 0.3s ease; 9 | } 10 | 11 | .rsssl-accordeon__header { 12 | /* Styling for the accordion header */ 13 | display: flex; 14 | justify-content: space-between; 15 | align-items: center; 16 | background-color: #f5f5f5; 17 | padding: 10px; 18 | cursor: pointer; 19 | } 20 | 21 | .rsssl-accordeon__header__inner { 22 | /* Styling for the inner container of the header */ 23 | display: flex; 24 | align-items: center; 25 | } 26 | 27 | .rsssl-accordeon__header__icon { 28 | /* You can set a background-image or other styling here for the icon */ 29 | width: 20px; 30 | height: 20px; 31 | margin-right: 10px; 32 | } 33 | 34 | .rsssl-accordeon__header__title { 35 | /* Styling for the title text */ 36 | font-size: 16px; 37 | font-weight: bold; 38 | } 39 | 40 | .rsssl-accordeon__header__button__inner { 41 | /* Styling for the button inside the header */ 42 | background: none; 43 | border: none; 44 | cursor: pointer; 45 | font-size: 18px; 46 | } 47 | 48 | .rsssl-accordeon__content { 49 | /* By default, hide the content */ 50 | max-height: 0; 51 | overflow: hidden; 52 | transition: max-height 0.3s ease; 53 | } 54 | -------------------------------------------------------------------------------- /assets/css/admin/modules/badges.scss: -------------------------------------------------------------------------------- 1 | .rsssl { 2 | .rsssl-badge { 3 | --badge-height: 20px; 4 | height: var(--badge-height); 5 | line-height: var(--badge-height); 6 | padding-inline: 8px; 7 | 8 | min-width: 100px; 9 | text-align: center; 10 | border-radius: var(--rsp-border-radius-xs); 11 | color: var(--rsp-white); 12 | display: table; 13 | margin: auto auto; 14 | font-size: var(--rsp-fs-100); 15 | 16 | &.rsp-dark { 17 | background-color: var(--rsp-black); 18 | color: var(--rsp-white); 19 | } 20 | 21 | &.rsp-low { 22 | background-color: var(--rsp-yellow-faded); 23 | color: var(--rsp-black); 24 | } 25 | 26 | &.rsp-medium { 27 | background-color: var(--rsp-yellow); 28 | color: var(--rsp-black); 29 | } 30 | 31 | &.rsp-high { 32 | background-color: var(--rsp-red-faded); 33 | color: var(--rsp-black); 34 | } 35 | 36 | &.rsp-critical { 37 | background-color: var(--rsp-red); 38 | color: var(--rsp-white); 39 | } 40 | 41 | &.rsp-success { 42 | background-color: var(--rsp-color-success); 43 | color: var(--rsp-white); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /assets/css/admin/modules/header.scss: -------------------------------------------------------------------------------- 1 | .rsssl-header-container .rsssl-header { 2 | display: flex; 3 | justify-content: space-between; 4 | height: 70px; 5 | box-sizing: border-box; 6 | 7 | img { 8 | margin: auto 0; 9 | height: 26px; 10 | } 11 | .rsssl-header-menu { 12 | display: flex; 13 | align-items: center; 14 | height: 100%; 15 | padding: 0 20px; 16 | box-sizing: border-box; 17 | .rsssl-header-menu-item { 18 | display: flex; 19 | align-items: center; 20 | height: 100%; 21 | padding: 0 20px; 22 | box-sizing: border-box; 23 | &:first-child { 24 | margin-left: 0; 25 | } 26 | &:last-child { 27 | margin-right: 0; 28 | } 29 | &.rsssl-header-menu-item-active { 30 | background-color: #f5f5f5; 31 | } 32 | } 33 | } 34 | .rsssl-header-actions { 35 | display: flex; 36 | align-items: center; 37 | margin-left: auto; 38 | gap: var(--rsp-spacing-s); 39 | 40 | select { 41 | max-width: 60ch; 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /assets/css/admin/modules/icons.scss: -------------------------------------------------------------------------------- 1 | .rsssl-icon{ 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | > div { 6 | display:flex; 7 | } 8 | svg{ 9 | fill: currentColor; 10 | } 11 | &-loading svg{ 12 | animation: spin 2s linear infinite; 13 | } 14 | 15 | @keyframes spin { 16 | 0% { transform: rotate(0deg); } 17 | 100% { transform: rotate(360deg); } 18 | } 19 | 20 | &.rsssl-click-animation{ 21 | animation: beat 0.4s ease-out; 22 | } 23 | } 24 | 25 | //loaders in buttons 26 | button.button .cmplz-icon.rsssl-icon-loading { 27 | padding-top: 6px; 28 | >div {line-height: inherit;} 29 | } 30 | -------------------------------------------------------------------------------- /assets/css/admin/modules/introcontainer.scss: -------------------------------------------------------------------------------- 1 | .rsssl-modal { 2 | 3 | //.rsssl-modal-header, .components-modal__header { 4 | // background-color: var(--rsp-yellow-faded); 5 | // padding: var(--rsp-spacing-m) var(--rsp-spacing-m)!important; 6 | // //no border radius on bottom 7 | // border-bottom-left-radius: 0; 8 | // border-bottom-right-radius: 0; 9 | // border-bottom: 0; 10 | //} 11 | // 12 | //.components-modal__content { 13 | // padding: 0; 14 | // &:before { 15 | // margin-bottom:initial; 16 | // } 17 | //} 18 | 19 | //.rsssl-header-extension { 20 | // background-color: var(--rsp-yellow-faded); 21 | // margin: 0; 22 | // padding: 0 var(--rsp-spacing-m); 23 | // p { 24 | // margin: 0; 25 | // padding: var(--rsp-spacing-m) 0; 26 | // padding-top: 0; 27 | // } 28 | //} 29 | 30 | .rsssl-intro-logo { 31 | width: 7em; 32 | position: absolute; 33 | right: 1.6em; 34 | height: auto; 35 | bottom: 0.15em; 36 | margin: 0; 37 | padding: 0; 38 | } 39 | 40 | @media (max-width: 768px) { 41 | .rsssl-intro-logo { 42 | display: none; 43 | } 44 | } 45 | 46 | .rsssl-ssl-intro-container { 47 | .rsssl-details { 48 | display: flex; 49 | padding: var(--rsp-spacing-xs) var(--rsp-spacing-m); 50 | gap: var(--rsp-spacing-xs); 51 | 52 | .rsssl-icon { 53 | min-width: 25px; 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /assets/css/admin/modules/new-features.scss: -------------------------------------------------------------------------------- 1 | .rsssl{ 2 | .rsssl-new-features-block{ 3 | .rsssl-grid-item-content{ 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: space-between; 7 | } 8 | } 9 | .rsssl-new-features{ 10 | display: flex; 11 | flex-direction: row; 12 | flex-wrap: wrap; 13 | gap: var(--rsp-spacing-xs); 14 | @media only screen and (max-width: $rsp-break-xxl) and (min-width: $rsp-break-m) { 15 | gap: var(--rsp-spacing-xxs); 16 | } 17 | } 18 | .rsssl-new-feature{ 19 | width: 100%; 20 | color: var(--rsp-text-color-light); 21 | display: flex; 22 | align-items: flex-start; 23 | min-width: 0; 24 | gap: var(--rsp-spacing-xs); 25 | text-decoration: none; 26 | .rsssl-icon{ 27 | margin-top: 2px; 28 | } 29 | .rsssl-new-feature-desc { 30 | p { 31 | font-size:var(--rsp-fs-300); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/notices.scss: -------------------------------------------------------------------------------- 1 | /** 2 | Admin notice 3 | */ 4 | 5 | -------------------------------------------------------------------------------- /assets/css/admin/modules/onboarding.scss: -------------------------------------------------------------------------------- 1 | .rsssl-modal.rsssl-onboarding { 2 | width: clamp(300px, 100ch, 100vw ); 3 | padding-top: var(--rsp-spacing-m); 4 | line-height: 2.2; 5 | min-height:295px; 6 | .rsssl-logo { 7 | height: 26px; 8 | } 9 | .rsssl-modal-content{ 10 | display:flex; 11 | min-height:295px; 12 | .rsssl-onboarding-placeholder { 13 | flex-grow:1 14 | } 15 | &-step { 16 | display:flex; 17 | flex-direction: column; 18 | width:100%; 19 | } 20 | .rsssl-processing { 21 | opacity:0.5; 22 | } 23 | 24 | ul{ 25 | li { 26 | .rsssl-icon{ 27 | margin-top: 7px; 28 | } 29 | .components-button.is-link { 30 | padding:5px 0; 31 | } 32 | } 33 | } 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/placeholder.scss: -------------------------------------------------------------------------------- 1 | @function randomNum($min, $max) { 2 | $rand: random(); 3 | $randomNum: $min + floor($rand * (($max - $min) + 1)); 4 | 5 | @return $randomNum; 6 | } 7 | 8 | $base-color: #ddd; 9 | $shine-color: #e8e8e8; 10 | $animation-duration: 1.6s; 11 | @mixin background-gradient { 12 | background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px); 13 | background-size: 600px; 14 | } 15 | .rsssl-datatable-placeholder { 16 | div { 17 | background-color:var(--rsp-grey-300); 18 | height:25px; 19 | &:nth-child(even) { 20 | background-color:#fff; 21 | } 22 | } 23 | } 24 | 25 | .rsssl-rest-error-message { 26 | margin:30px; 27 | ul { 28 | list-style:disc; 29 | margin:20px; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /assets/css/admin/modules/ssltest.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/admin/modules/ssltest.scss -------------------------------------------------------------------------------- /assets/css/admin/modules/tips-tricks.scss: -------------------------------------------------------------------------------- 1 | .rsssl-tips_tricks{ 2 | .rsssl-grid-item-header{ 3 | .rsssl-grid-item-controls{ 4 | height: 28px; 5 | } 6 | } 7 | } 8 | .rsssl-tips-tricks-container { 9 | display: flex !important; 10 | flex-direction: row; 11 | flex-wrap: wrap; 12 | margin-bottom: 10px; 13 | font-size: var(--rsp-fs-300); 14 | line-height: 1.7; 15 | gap: var(--rsp-spacing-xxs); 16 | 17 | @media screen and (max-width: 992px) { 18 | flex-direction: row; 19 | overflow: hidden; 20 | } 21 | 22 | .rsssl-tips-tricks-element { 23 | width: calc(50% - var(--rsp-spacing-xxs)); 24 | @media( max-width: $rsp-break-xs ){ 25 | width: 100%; 26 | } 27 | a { 28 | color: var(--rsp-text-color-light); 29 | transition: color 0.3s ease; 30 | display: flex; 31 | align-items: center; 32 | gap: var(--rsp-spacing-xs); 33 | min-width: 0; /* or some value */ 34 | text-decoration: none; 35 | 36 | &:hover { 37 | color: var(--rsp-brand-primary); 38 | text-decoration: underline; 39 | 40 | svg path{ 41 | fill: var(--rsp-brand-primary); 42 | } 43 | 44 | .rsssl-tips-tricks-content { 45 | text-decoration: underline; 46 | } 47 | } 48 | } 49 | 50 | .rsssl-bullet { 51 | transition: background-color 0.3s ease; 52 | background-color: var(--rsp-grey-300); 53 | } 54 | .rsssl-tips-tricks-content { 55 | white-space: nowrap; 56 | overflow: hidden; 57 | text-overflow: ellipsis; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/_closeButton.scss: -------------------------------------------------------------------------------- 1 | .#{$rt-namespace}__close-button { 2 | color: #fff; 3 | background: transparent; 4 | outline: none; 5 | border: none; 6 | padding: 0; 7 | cursor: pointer; 8 | opacity: 0.7; 9 | transition: 0.3s ease; 10 | align-self: flex-start; 11 | 12 | &--light { 13 | color: #000; 14 | opacity: 0.3; 15 | } 16 | 17 | & > svg { 18 | fill: currentColor; 19 | height: 16px; 20 | width: 14px; 21 | } 22 | 23 | &:hover, 24 | &:focus { 25 | opacity: 1; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/_icons.scss: -------------------------------------------------------------------------------- 1 | .#{$rt-namespace}__spinner { 2 | width: 20px; 3 | height: 20px; 4 | box-sizing: border-box; 5 | border: 2px solid; 6 | border-radius: 100%; 7 | border-color: var(--toastify-spinner-color-empty-area); 8 | border-right-color: var(--toastify-spinner-color); 9 | animation: #{$rt-namespace}__spin 0.65s linear infinite; 10 | } 11 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/_progressBar.scss: -------------------------------------------------------------------------------- 1 | @keyframes #{$rt-namespace}__trackProgress { 2 | 0% { 3 | transform: scaleX(1); 4 | } 5 | 100% { 6 | transform: scaleX(0); 7 | } 8 | } 9 | 10 | .#{$rt-namespace}__progress-bar { 11 | position: absolute; 12 | bottom: 0; 13 | left: 0; 14 | width: 100%; 15 | height: 5px; 16 | z-index: var(--toastify-z-index); 17 | opacity: 0.7; 18 | transform-origin: left; 19 | 20 | &--animated { 21 | animation: #{$rt-namespace}__trackProgress linear 1 forwards; 22 | } 23 | 24 | &--controlled { 25 | transition: transform 0.2s; 26 | } 27 | 28 | &--rtl { 29 | right: 0; 30 | left: initial; 31 | transform-origin: right; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/_toast.scss: -------------------------------------------------------------------------------- 1 | .#{$rt-namespace}__toast { 2 | position: relative; 3 | min-height: var(--toastify-toast-min-height); 4 | box-sizing: border-box; 5 | margin-bottom: 1rem; 6 | padding: 8px; 7 | border-radius: var(--rsp-border-radius); 8 | border: 1px solid #eeeeee; 9 | box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1), 0 2px 15px 0 rgba(0, 0, 0, 0.05); 10 | box-shadow: var(--rsp-box-shadow); 11 | display: flex; 12 | justify-content: space-between; 13 | max-height: var(--toastify-toast-max-height); 14 | overflow: hidden; 15 | font-family: var(--toastify-font-family); 16 | cursor: default; 17 | direction: ltr; 18 | /* webkit only issue #791 */ 19 | z-index: 0; 20 | &--rtl { 21 | direction: rtl; 22 | } 23 | &--close-on-click { 24 | cursor: pointer; 25 | } 26 | &-body { 27 | margin: auto 0; 28 | flex: 1 1 auto; 29 | padding: 6px; 30 | display: flex; 31 | align-items: center; 32 | & > div:last-child { 33 | word-break: break-word; 34 | flex: 1; 35 | } 36 | } 37 | &-icon { 38 | margin-inline-end: 10px; 39 | width: 20px; 40 | flex-shrink: 0; 41 | display: flex; 42 | } 43 | } 44 | 45 | .#{$rt-namespace}--animate { 46 | animation-fill-mode: both; 47 | animation-duration: 0.7s; 48 | } 49 | 50 | .#{$rt-namespace}--animate-icon { 51 | animation-fill-mode: both; 52 | animation-duration: 0.3s; 53 | } 54 | 55 | @media #{$rt-mobile} { 56 | .#{$rt-namespace}__toast { 57 | margin-bottom: 0; 58 | border-radius: 0; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/_toastContainer.scss: -------------------------------------------------------------------------------- 1 | .#{$rt-namespace}__toast-container { 2 | z-index: var(--toastify-z-index); 3 | -webkit-transform: translate3d(0, 0, var(--toastify-z-index) px); 4 | position: fixed; 5 | padding: 4px; 6 | width: var(--toastify-toast-width); 7 | box-sizing: border-box; 8 | color: #fff; 9 | &--top-left { 10 | top: 1em; 11 | left: 1em; 12 | } 13 | &--top-center { 14 | top: calc( 2em + 32px); 15 | left: 50%; 16 | transform: translateX(-50%); 17 | } 18 | &--top-right { 19 | top: 1em; 20 | right: 1em; 21 | } 22 | &--bottom-left { 23 | bottom: 1em; 24 | left: 1em; 25 | } 26 | &--bottom-center { 27 | bottom: 1em; 28 | left: 50%; 29 | transform: translateX(-50%); 30 | } 31 | &--bottom-right { 32 | bottom: 1em; 33 | right: 1em; 34 | } 35 | } 36 | 37 | @media #{$rt-mobile} { 38 | .#{$rt-namespace}__toast-container { 39 | width: 100vw; 40 | padding: 0; 41 | left: 0; 42 | margin: 0; 43 | &--top-left, 44 | &--top-center, 45 | &--top-right { 46 | top: 0; 47 | transform: translateX(0); 48 | } 49 | &--bottom-left, 50 | &--bottom-center, 51 | &--bottom-right { 52 | bottom: 0; 53 | transform: translateX(0); 54 | } 55 | &--rtl { 56 | right: 0; 57 | left: initial; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/animations/_flip.scss: -------------------------------------------------------------------------------- 1 | @keyframes #{$rt-namespace}__flipIn { 2 | from { 3 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 4 | animation-timing-function: ease-in; 5 | opacity: 0; 6 | } 7 | 40% { 8 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 9 | animation-timing-function: ease-in; 10 | } 11 | 60% { 12 | transform: perspective(400px) rotate3d(1, 0, 0, 10deg); 13 | opacity: 1; 14 | } 15 | 80% { 16 | transform: perspective(400px) rotate3d(1, 0, 0, -5deg); 17 | } 18 | to { 19 | transform: perspective(400px); 20 | } 21 | } 22 | 23 | @keyframes #{$rt-namespace}__flipOut { 24 | from { 25 | transform: perspective(400px); 26 | } 27 | 30% { 28 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 29 | opacity: 1; 30 | } 31 | to { 32 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 33 | opacity: 0; 34 | } 35 | } 36 | 37 | .#{$rt-namespace}__flip-enter { 38 | animation-name: #{$rt-namespace}__flipIn; 39 | } 40 | 41 | .#{$rt-namespace}__flip-exit { 42 | animation-name: #{$rt-namespace}__flipOut; 43 | } 44 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/animations/_spin.scss: -------------------------------------------------------------------------------- 1 | @keyframes #{$rt-namespace}__spin { 2 | from { 3 | transform: rotate(0deg); 4 | } 5 | to { 6 | transform: rotate(360deg); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/animations/_zoom.scss: -------------------------------------------------------------------------------- 1 | @keyframes #{$rt-namespace}__zoomIn { 2 | from { 3 | opacity: 0; 4 | transform: scale3d(0.3, 0.3, 0.3); 5 | } 6 | 50% { 7 | opacity: 1; 8 | } 9 | } 10 | 11 | @keyframes #{$rt-namespace}__zoomOut { 12 | from { 13 | opacity: 1; 14 | } 15 | 50% { 16 | opacity: 0; 17 | transform: scale3d(0.3, 0.3, 0.3); 18 | } 19 | to { 20 | opacity: 0; 21 | } 22 | } 23 | 24 | .#{$rt-namespace}__zoom-enter { 25 | animation-name: #{$rt-namespace}__zoomIn; 26 | } 27 | 28 | .#{$rt-namespace}__zoom-exit { 29 | animation-name: #{$rt-namespace}__zoomOut; 30 | } 31 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/main.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import 'variables'; 4 | @import 'toastContainer'; 5 | @import 'toast'; 6 | @import 'theme'; 7 | @import 'closeButton'; 8 | @import 'progressBar'; 9 | @import 'icons'; 10 | 11 | // entrance and exit animations 12 | @import 'animations/bounce.scss'; 13 | @import 'animations/zoom.scss'; 14 | @import 'animations/flip.scss'; 15 | @import 'animations/slide.scss'; 16 | @import 'animations/spin.scss'; 17 | -------------------------------------------------------------------------------- /assets/css/admin/modules/toast/minimal.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import 'variables'; 4 | 5 | @keyframes #{$rt-namespace}__trackProgress { 6 | 0% { 7 | transform: scaleX(1); 8 | } 9 | 100% { 10 | transform: scaleX(0); 11 | } 12 | } 13 | 14 | .#{$rt-namespace}__progress-bar { 15 | animation: #{$rt-namespace}__trackProgress linear 1 forwards; 16 | } 17 | -------------------------------------------------------------------------------- /assets/css/admin/modules/tooltip.scss: -------------------------------------------------------------------------------- 1 | .rsssl div[class^=rsssl-wizard-] { 2 | .rsssl-tooltip-icon .react-tooltip { 3 | max-width:300px; 4 | white-space: pre-wrap; 5 | } 6 | .rsssl-field-wrap { 7 | 8 | label { 9 | display: flex; 10 | 11 | .cmplz-label-text { 12 | margin-right: 10px; 13 | } 14 | } 15 | 16 | .rsssl-icon { 17 | cursor: pointer; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/two-fa.scss: -------------------------------------------------------------------------------- 1 | a.rsssl-skip-link { 2 | display: flex; 3 | justify-content: center; 4 | margin: 15px 0 20px; 5 | } 6 | 7 | .rsssl-two_fa_users div[data-column-id="5"].rdt_TableCol { 8 | display: none; 9 | } 10 | 11 | .rsssl-two_fa_users .rdt_TableRow .rdt_TableCell:last-child { 12 | flex: 1; 13 | display: flex; 14 | justify-content: flex-end; 15 | } 16 | 17 | .rsssl-two_fa_users .rdt_TableHeadRow .rdt_TableCol:last-child { 18 | flex-grow: 1; 19 | display: flex; 20 | justify-content: flex-end; 21 | } 22 | 23 | .rsssl-two_fa_general, 24 | .rsssl-two_fa_email, 25 | .rsssl-two_fa_totp, 26 | .rsssl-two_fa_users { 27 | .MuiPopper-root, .MuiPaper-root { 28 | max-height: 30px; 29 | z-index: 15; 30 | 31 | div { 32 | font-family: inherit !important; 33 | } 34 | 35 | ul { 36 | max-height: initial; 37 | } 38 | } 39 | } 40 | 41 | .rsssl-add-button__inner .button { 42 | display: flex; 43 | align-items: center; 44 | } 45 | 46 | .rsssl-add-button__inner .button .icon { 47 | margin-left: 8px; /* Adjust the spacing as needed */ 48 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/wizard/learning-mode.scss: -------------------------------------------------------------------------------- 1 | .rsssl-learningmode-placeholder { 2 | height:150px; 3 | div { 4 | background-color:var(--rsp-grey-200); 5 | margin:10px 0; 6 | height:20px; 7 | } 8 | } 9 | 10 | .rsssl-learning-mode-delete { 11 | cursor: pointer; 12 | background: none; 13 | border: none; 14 | font-size: 1.5em; 15 | font-weight: 700; 16 | } 17 | .rsssl-locked-overlay { 18 | .rsssl-open { 19 | float: left; 20 | margin-right: 12px; 21 | } 22 | 23 | .rsssl-progress-status { 24 | @extend .rsssl-task-status; 25 | &.rsssl-learning-mode-completed, &.rsssl-learning-mode-enforced { 26 | background-color: var(--rsp-color-success); 27 | color:#fff; 28 | } 29 | &.rsssl-learning-mode { 30 | background-color: var(--rsp-color-open); 31 | 32 | } 33 | &.rsssl-learning-mode-error { 34 | background-color: var(--rsp-color-error); 35 | color:#fff; 36 | 37 | } 38 | &.rsssl-disabled, &.rsssl-learning-mode-disabled { 39 | background-color: var(--rsp-color-disabled); 40 | } 41 | 42 | } 43 | } 44 | 45 | .rsssl-learning-mode-footer { 46 | display:flex; 47 | align-items: center; 48 | justify-content: flex-start; 49 | gap: var(--rsp-spacing-s); 50 | select { 51 | margin-left:auto; 52 | } 53 | label { 54 | display: flex; 55 | align-items: center; 56 | input{ 57 | margin-top: 0; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/wizard/mixed-content-scan.scss: -------------------------------------------------------------------------------- 1 | .rsssl-mixed-content-scan { 2 | .rsssl-mixed-content-placeholder { 3 | height:250px; 4 | div { 5 | background-color:var(--rsp-grey-200); 6 | margin:10px 0; 7 | height:20px; 8 | } 9 | } 10 | //.rsssl-shield-overlay { 11 | // height:250px; 12 | // align-items: center; 13 | // justify-content: center; 14 | // display:flex; 15 | //} 16 | 17 | .rsssl-field-wrap { 18 | .rdt_TableCell[data-column-id="2"] { 19 | display:grid; 20 | } 21 | .rdt_TableCol, .rdt_TableCell { 22 | min-width: 110px; 23 | 24 | } 25 | } 26 | 27 | .rsssl-progress-container { 28 | .rsssl-progress-bar { 29 | border-radius:5px; 30 | height:20px; 31 | background-color:var(--rsp-green); 32 | } 33 | } 34 | .rsssl-task-status{ 35 | min-width: min-content; 36 | &.rsssl-warning { 37 | background-color: var(--rsp-yellow); 38 | color: var(--rsp-text-color); 39 | } 40 | } 41 | button.button{ 42 | line-height: 1.5; 43 | min-height: 10px; 44 | } 45 | .rsssl-grid-item-content-footer{ 46 | display: flex; 47 | gap: var(--rsp-spacing-s); 48 | } 49 | .rsssl-current-scan-action, .rsssl-mixed-content-description { 50 | margin:10px 5px; 51 | font-size: var(--rsp-fs-300); 52 | } 53 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/wizard/permissions-policy.scss: -------------------------------------------------------------------------------- 1 | .rsssl div[class^=rsssl-wizard-] { 2 | .rsssl-permissions_policy { 3 | .rdt_TableCell , .rdt_TableCol{ 4 | min-width:fit-content; 5 | } 6 | .rsssl-locked .rsssl-shield-overlay { 7 | top:calc(100% - 300px); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/wizard/snackbar.scss: -------------------------------------------------------------------------------- 1 | .rsssl{ 2 | .components-snackbar-list.edit-site-notices{ 3 | width: max-content; 4 | position: fixed; 5 | bottom: var(--rsp-spacing-m); 6 | right: var(--rsp-spacing-l); 7 | & > div{ 8 | margin-left: auto; 9 | } 10 | .components-snackbar{ 11 | @include rsssl-block; 12 | color: var(--rsp-color-success); 13 | background-color: #fff; 14 | font-weight:700; 15 | font-size:14px; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/wizard/vulnerabilities.scss: -------------------------------------------------------------------------------- 1 | .rsssl-vulnerability-action { 2 | a.button { 3 | margin-left:10px; 4 | } 5 | } 6 | 7 | .rsssl-processing { 8 | opacity:0.5; 9 | } 10 | .rsssl-vulnerabilities_measures-overview { 11 | .allowRowEvents { 12 | .wp-core-ui select { 13 | max-width: 100%; 14 | } 15 | } 16 | .rdt_TableCell { 17 | &:nth-child(2) { 18 | select { 19 | max-width: 100%; 20 | } 21 | } 22 | } 23 | } 24 | 25 | .rsssl-vulnerabilities_measures { 26 | .rsssl-locked-overlay { 27 | input[type=checkbox] { 28 | margin-top: 0; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /assets/css/admin/modules/xml-rpc.scss: -------------------------------------------------------------------------------- 1 | .rsssl div[class^=rsssl-wizard-] .rsssl-hardening-xml { 2 | .rsssl-locked .rsssl-shield-overlay { 3 | align-items: center; 4 | display: flex; 5 | justify-content: center; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /assets/css/admin/states.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/admin/states.scss -------------------------------------------------------------------------------- /assets/css/admin/theme.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/admin/theme.scss -------------------------------------------------------------------------------- /assets/css/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/css/rsssl-plugin.css: -------------------------------------------------------------------------------- 1 | /* 2 | This was created for styling the plugin overview page for vulnerable plugins. 3 | */ 4 | .rsssl-btn-vulnerable { 5 | display: inline-block; 6 | text-decoration: none; 7 | font-size: var(--rsp-fs-100); 8 | line-height: 2.15384615; 9 | min-height: 30px; 10 | margin: 0; 11 | padding: 4px 8px; 12 | min-width: 100px; 13 | text-align: center; 14 | cursor: pointer; 15 | font-weight: 600; 16 | -webkit-appearance: none; 17 | border-radius: var(--rsp-border-radius-xs); 18 | white-space: nowrap; 19 | box-sizing: border-box; 20 | background-color: var(--rsp-yellow); 21 | color: var(--rsp-black); 22 | border-color: var(--rsp-yellow); 23 | } 24 | 25 | .rsssl-btn-vulnerable:hover { 26 | text-decoration: underline; 27 | } 28 | 29 | .rsssl-btn-vulnerable.rsssl-critical { 30 | background-color: var(--rsp-red); 31 | color: var(--rsp-white); 32 | border-color: var(--rsp-red); 33 | } 34 | 35 | .rsssl-btn-vulnerable.rsssl-high { 36 | background-color: var(--rsp-red); 37 | color: var(--rsp-white); 38 | border-color: var(--rsp-red); 39 | } 40 | 41 | .rsssl-btn-vulnerable.rsssl-medium { 42 | border-color: var(--rsp-yellow); 43 | color: var(--rsp-black); 44 | background-color: var(--rsp-yellow); 45 | } -------------------------------------------------------------------------------- /assets/css/rsssl-plugin.min.css: -------------------------------------------------------------------------------- 1 | .rsssl-btn-vulnerable{display:inline-block;text-decoration:none;font-size:var(--rsp-fs-100);line-height:2.15384615;min-height:30px;margin:0;padding:4px 8px;min-width:100px;text-align:center;cursor:pointer;font-weight:600;-webkit-appearance:none;border-radius:var(--rsp-border-radius-xs);white-space:nowrap;box-sizing:border-box;background-color:var(--rsp-yellow);color:var(--rsp-black);border-color:var(--rsp-yellow)}.rsssl-btn-vulnerable:hover{text-decoration:underline}.rsssl-btn-vulnerable.rsssl-critical{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-high{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-medium{border-color:var(--rsp-yellow);color:var(--rsp-black);background-color:var(--rsp-yellow)} -------------------------------------------------------------------------------- /assets/css/rsssl-plugin.scss: -------------------------------------------------------------------------------- 1 | /* 2 | This was created for styling the plugin overview page for vulnerable plugins. 3 | */ 4 | @import "variables.scss"; 5 | 6 | .rsssl-btn-vulnerable { 7 | display: inline-block; 8 | text-decoration: none; 9 | font-size: var(--rsp-fs-100); 10 | line-height: 2.15384615; 11 | min-height: 30px; 12 | margin: 0; 13 | padding: 4px 8px; 14 | min-width: 100px; 15 | text-align: center; 16 | cursor: pointer; 17 | font-weight: 600; 18 | -webkit-appearance: none; 19 | border-radius: var(--rsp-border-radius-xs); 20 | white-space: nowrap; 21 | box-sizing: border-box; 22 | background-color: var(--rsp-yellow); 23 | color: var(--rsp-black); 24 | border-color: var(--rsp-yellow); 25 | &:hover { 26 | text-decoration: underline; 27 | } 28 | 29 | &.rsssl-critical { 30 | background-color: var(--rsp-red); 31 | color: var(--rsp-white); 32 | border-color: var(--rsp-red); 33 | } 34 | 35 | &.rsssl-high { 36 | background-color: var(--rsp-red); 37 | color: var(--rsp-white); 38 | border-color: var(--rsp-red); 39 | } 40 | 41 | &.rsssl-medium { 42 | border-color: var(--rsp-yellow); 43 | color: var(--rsp-black); 44 | background-color: var(--rsp-yellow); 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /assets/css/rtl/plugin.min.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/rtl/plugin.min.css -------------------------------------------------------------------------------- /assets/css/rtl/rsssl-plugin.min.css: -------------------------------------------------------------------------------- 1 | .rsssl-btn-vulnerable{display:inline-block;text-decoration:none;font-size:var(--rsp-fs-100);line-height:2.15384615;min-height:30px;margin:0;padding:4px 8px;min-width:100px;text-align:center;cursor:pointer;font-weight:600;-webkit-appearance:none;border-radius:var(--rsp-border-radius-xs);white-space:nowrap;box-sizing:border-box;background-color:var(--rsp-yellow);color:var(--rsp-black);border-color:var(--rsp-yellow)}.rsssl-btn-vulnerable:hover{text-decoration:underline}.rsssl-btn-vulnerable.rsssl-critical{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-high{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-medium{border-color:var(--rsp-yellow);color:var(--rsp-black);background-color:var(--rsp-yellow)} -------------------------------------------------------------------------------- /assets/css/variables.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/css/variables.scss -------------------------------------------------------------------------------- /assets/features/two-fa/assets.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => 'f0d22c3325649a69f214'); 2 | -------------------------------------------------------------------------------- /assets/features/two-fa/styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => 'b897dd9d63eac60482f7'); 2 | -------------------------------------------------------------------------------- /assets/features/two-fa/styles.min.js: -------------------------------------------------------------------------------- 1 | /******/ (() => { // webpackBootstrap 2 | /******/ "use strict"; 3 | /******/ // The require scope 4 | /******/ var __webpack_require__ = {}; 5 | /******/ 6 | /************************************************************************/ 7 | /******/ /* webpack/runtime/make namespace object */ 8 | /******/ (() => { 9 | /******/ // define __esModule on exports 10 | /******/ __webpack_require__.r = (exports) => { 11 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 12 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 13 | /******/ } 14 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 15 | /******/ }; 16 | /******/ })(); 17 | /******/ 18 | /************************************************************************/ 19 | var __webpack_exports__ = {}; 20 | /*!***********************************************************!*\ 21 | !*** ../security/wordpress/two-fa/assets/css/two-fa.scss ***! 22 | \***********************************************************/ 23 | __webpack_require__.r(__webpack_exports__); 24 | // extracted by mini-css-extract-plugin 25 | 26 | /******/ })() 27 | ; 28 | //# sourceMappingURL=styles.min.js.map -------------------------------------------------------------------------------- /assets/features/two-fa/styles.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"two-fa/styles.min.js","mappings":";;UAAA;UACA;;;;;WCDA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;;;;;ACNA","sources":["webpack://really-simple-ssl/webpack/bootstrap","webpack://really-simple-ssl/webpack/runtime/make namespace object","webpack://really-simple-ssl/../security/wordpress/two-fa/assets/css/two-fa.scss?e6ff"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// extracted by mini-css-extract-plugin\nexport {};"],"names":[],"sourceRoot":""} -------------------------------------------------------------------------------- /assets/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/img/.DS_Store -------------------------------------------------------------------------------- /assets/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/img/icon.png -------------------------------------------------------------------------------- /assets/img/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/img/index.php -------------------------------------------------------------------------------- /assets/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/js/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/assets/js/.DS_Store -------------------------------------------------------------------------------- /assets/templates/passkey/login.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | 5 | 6 |

7 |

8 | 9 | 10 |

11 |

12 | 15 |

16 |

17 | 18 | 19 |

20 |
21 |
22 | -------------------------------------------------------------------------------- /assets/templates/two_fa/expired.php: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 |
5 |

6 | 7 |

8 |
9 | 11 |

12 | 17 |
18 | roles; 22 | // If this is in the forced roles, we do not show the "disable" link. 23 | ?> 24 |

25 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /languages/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lets-encrypt/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "fbett/le_acme2": "^1.5", 4 | "plesk/api-php-lib": "^1.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /lets-encrypt/composer.phar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/lets-encrypt/composer.phar -------------------------------------------------------------------------------- /lets-encrypt/config/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lets-encrypt/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lets-encrypt/integrations/directadmin/functions.php: -------------------------------------------------------------------------------- 1 | letsencrypt_handler->get_subjects(); 8 | $response = $directadmin->installSSL($domains); 9 | if ( $response->status === 'success' ) { 10 | update_option('rsssl_le_certificate_installed_by_rsssl', 'directadmin', false ); 11 | } 12 | return $response; 13 | } else { 14 | $status = 'error'; 15 | $action = 'stop'; 16 | $message = __("The system is not ready for the installation yet. Please run the wizard again.", "really-simple-ssl"); 17 | return new RSSSL_RESPONSE($status, $action, $message); 18 | } 19 | } 20 | 21 | /** 22 | * Add actions for direct admin 23 | * @param array $fields 24 | * 25 | * @return array 26 | */ 27 | function rsssl_directadmin_add_condition_actions($fields){ 28 | $directadmin = new rsssl_directadmin(); 29 | if ( $directadmin->credentials_available() ) { 30 | $index = array_search( 'installation', array_column( $fields, 'id' ) ); 31 | //clear existing array 32 | $fields[ $index ]['actions'] = []; 33 | $fields[ $index ]['actions'][] 34 | = array( 35 | 'description' => __( "Attempting to install certificate...", "really-simple-ssl" ), 36 | 'action' => 'rsssl_install_directadmin', 37 | 'attempts' => 1, 38 | 'status' => 'inactive', 39 | ); 40 | } 41 | 42 | return $fields; 43 | } 44 | add_filter( 'rsssl_fields', 'rsssl_directadmin_add_condition_actions' ); 45 | 46 | 47 | -------------------------------------------------------------------------------- /lets-encrypt/integrations/hostgator/hostgator.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lets-encrypt/integrations/integrations.php: -------------------------------------------------------------------------------- 1 | letsencrypt_handler->get_subjects(); 8 | $response = $cpanel->installSSL($domains); 9 | if ( $response->status === 'success' ) { 10 | update_option('rsssl_le_certificate_installed_by_rsssl', 'cpanel:default', false); 11 | } 12 | return $response; 13 | } else { 14 | $status = 'error'; 15 | $action = 'stop'; 16 | $message = __("The system is not ready for the installation yet. Please run the wizard again.", "really-simple-ssl"); 17 | return new RSSSL_RESPONSE($status, $action, $message); 18 | } 19 | } 20 | 21 | /** 22 | * Add the step to install SSL using Plesk 23 | * @param array $fields 24 | * 25 | * @return array 26 | */ 27 | function rsssl_plesk_add_installation_step($fields){ 28 | $plesk = new rsssl_plesk(); 29 | if ( $plesk->credentials_available() ) { 30 | $index = array_search( 'installation', array_column( $fields, 'id' ) ); 31 | $fields[ $index ]['actions'] = array_merge(array( 32 | array( 33 | 'description' => __("Installing SSL certificate using PLESK API...", "really-simple-ssl"), 34 | 'action'=> 'rsssl_plesk_install', 35 | 'attempts' => 1, 36 | 'status' => 'inactive', 37 | ) 38 | ) , $fields[ $index ]['actions'] ); 39 | } 40 | 41 | return $fields; 42 | } 43 | add_filter( 'rsssl_fields', 'rsssl_plesk_add_installation_step' ); 44 | -------------------------------------------------------------------------------- /lets-encrypt/node_modules/composer/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-present, Brian Woodward. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /lets-encrypt/node_modules/composer/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/generator'); 2 | -------------------------------------------------------------------------------- /lets-encrypt/node_modules/composer/lib/timer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { nano } = require('./utils'); 4 | 5 | class Timer { 6 | constructor() { 7 | this.date = {}; 8 | this.hr = {}; 9 | } 10 | 11 | start() { 12 | this.date.start = new Date(); 13 | this.hr.start = process.hrtime(); 14 | return this; 15 | } 16 | 17 | end() { 18 | this.date.end = new Date(); 19 | this.hr.end = process.hrtime(); 20 | this.hr.duration = process.hrtime(this.hr.start); 21 | return this; 22 | } 23 | 24 | get diff() { 25 | return nano(this.hr.end) - nano(this.hr.start); 26 | } 27 | 28 | get duration() { 29 | return this.hr.duration ? require('pretty-time')(this.hr.duration) : ''; 30 | } 31 | } 32 | 33 | /** 34 | * Expose `Timer` 35 | */ 36 | 37 | module.exports = Timer; 38 | -------------------------------------------------------------------------------- /lets-encrypt/node_modules/composer/lib/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Get hr time in nanoseconds 5 | */ 6 | 7 | const nano = time => +time[0] * 1e9 + +time[1]; 8 | 9 | /** 10 | * Flatten an array 11 | */ 12 | 13 | const flatten = arr => [].concat.apply([], arr); 14 | 15 | /** 16 | * Return true if `val` is an object 17 | */ 18 | 19 | const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 20 | 21 | /** 22 | * Create an options object from the given arguments. 23 | * @param {object} `app` 24 | * @param {...[function|string|object]} `rest` 25 | * @return {object} 26 | */ 27 | 28 | const createOptions = (app, expand, ...rest) => { 29 | const args = flatten(rest); 30 | const config = args.find(val => isObject(val) && !val.isTask) || {}; 31 | const options = Object.assign({}, app.options, config); 32 | const tasks = expand === true 33 | ? app.expandTasks(args.filter(val => val && val !== config)) 34 | : args.filter(val => val && val !== config); 35 | return { tasks, options }; 36 | }; 37 | 38 | /** 39 | * Noop for tasks 40 | */ 41 | 42 | const noop = cb => cb(); 43 | 44 | /** 45 | * Create a non-enumerable property on `obj` 46 | */ 47 | 48 | const define = (obj, key, value) => { 49 | Reflect.defineProperty(obj, key, { 50 | configurable: true, 51 | enumerable: false, 52 | writable: true, 53 | value 54 | }); 55 | }; 56 | 57 | /** 58 | * Expose "utils" 59 | */ 60 | 61 | module.exports = { 62 | createOptions, 63 | define, 64 | flatten, 65 | isObject, 66 | nano, 67 | noop 68 | }; 69 | -------------------------------------------------------------------------------- /lets-encrypt/node_modules/pretty-time/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-present, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /lets-encrypt/node_modules/pretty-time/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * pretty-time 3 | * 4 | * Copyright (c) 2015-2018, present, Jon Schlinkert. 5 | * Released under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const utils = require('./utils'); 11 | 12 | module.exports = (time, smallest, digits) => { 13 | const isNumber = /^[0-9]+$/.test(time); 14 | if (!isNumber && !Array.isArray(time)) { 15 | throw new TypeError('expected an array or number in nanoseconds'); 16 | } 17 | if (Array.isArray(time) && time.length !== 2) { 18 | throw new TypeError('expected an array from process.hrtime()'); 19 | } 20 | 21 | if (/^[0-9]+$/.test(smallest)) { 22 | digits = smallest; 23 | smallest = null; 24 | } 25 | 26 | let num = isNumber ? time : utils.nano(time); 27 | let res = ''; 28 | let prev; 29 | 30 | for (const uom of Object.keys(utils.scale)) { 31 | const step = utils.scale[uom]; 32 | let inc = num / step; 33 | 34 | if (smallest && utils.isSmallest(uom, smallest)) { 35 | inc = utils.round(inc, digits); 36 | if (prev && (inc === (prev / step))) --inc; 37 | res += inc + uom; 38 | return res.trim(); 39 | } 40 | 41 | if (inc < 1) continue; 42 | if (!smallest) { 43 | inc = utils.round(inc, digits); 44 | res += inc + uom; 45 | return res; 46 | } 47 | 48 | prev = step; 49 | 50 | inc = Math.floor(inc); 51 | num -= (inc * step); 52 | res += inc + uom + ' '; 53 | } 54 | 55 | return res.trim(); 56 | }; 57 | -------------------------------------------------------------------------------- /lets-encrypt/node_modules/pretty-time/utils.js: -------------------------------------------------------------------------------- 1 | exports.nano = time => +time[0] * 1e9 + +time[1]; 2 | 3 | exports.scale = { 4 | 'w': 6048e11, 5 | 'd': 864e11, 6 | 'h': 36e11, 7 | 'm': 6e10, 8 | 's': 1e9, 9 | 'ms': 1e6, 10 | 'μs': 1e3, 11 | 'ns': 1, 12 | }; 13 | 14 | exports.regex = { 15 | 'w': /^(w((ee)?k)?s?)$/, 16 | 'd': /^(d(ay)?s?)$/, 17 | 'h': /^(h((ou)?r)?s?)$/, 18 | 'm': /^(min(ute)?s?|m)$/, 19 | 's': /^((sec(ond)?)s?|s)$/, 20 | 'ms': /^(milli(second)?s?|ms)$/, 21 | 'μs': /^(micro(second)?s?|μs)$/, 22 | 'ns': /^(nano(second)?s?|ns?)$/, 23 | }; 24 | 25 | exports.isSmallest = function(uom, unit) { 26 | return exports.regex[uom].test(unit); 27 | }; 28 | 29 | exports.round = function(num, digits) { 30 | const n = Math.abs(num); 31 | return /[0-9]/.test(digits) ? n.toFixed(digits) : Math.round(n); 32 | }; 33 | -------------------------------------------------------------------------------- /lets-encrypt/node_modules/use/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-present, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /lets-encrypt/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "composer": { 6 | "version": "4.1.0", 7 | "resolved": "https://registry.npmjs.org/composer/-/composer-4.1.0.tgz", 8 | "integrity": "sha512-qIIoNYjwFHrQFUdB8kD3pZs30+JeYK9149EpOYr/NVrii00KMO31IonzZMeRSU4qazyWZpEgVzkBmQ6VFWxedA==", 9 | "requires": { 10 | "pretty-time": "^1.1.0", 11 | "use": "^3.1.1" 12 | } 13 | }, 14 | "pretty-time": { 15 | "version": "1.1.0", 16 | "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", 17 | "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" 18 | }, 19 | "use": { 20 | "version": "3.1.1", 21 | "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", 22 | "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/autoload.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/composer/InstalledVersions.php', 10 | ); 11 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/composer/autoload_namespaces.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/fbett/le_acme2/src'), 10 | ); 11 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/composer/autoload_psr4.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/plesk/api-php-lib/src'), 10 | ); 11 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/composer/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/composer/installed.php: -------------------------------------------------------------------------------- 1 | 3 | array ( 4 | 'pretty_version' => 'dev-master', 5 | 'version' => 'dev-master', 6 | 'aliases' => 7 | array ( 8 | ), 9 | 'reference' => '53cfe01c831d81b1398d479a9e85cbb4110e9e13', 10 | 'name' => '__root__', 11 | ), 12 | 'versions' => 13 | array ( 14 | '__root__' => 15 | array ( 16 | 'pretty_version' => 'dev-master', 17 | 'version' => 'dev-master', 18 | 'aliases' => 19 | array ( 20 | ), 21 | 'reference' => '53cfe01c831d81b1398d479a9e85cbb4110e9e13', 22 | ), 23 | 'fbett/le_acme2' => 24 | array ( 25 | 'pretty_version' => '1.5.6', 26 | 'version' => '1.5.6.0', 27 | 'aliases' => 28 | array ( 29 | ), 30 | 'reference' => '26b2c421764b173326f6bcb0713a86bd614f77fa', 31 | ), 32 | 'plesk/api-php-lib' => 33 | array ( 34 | 'pretty_version' => 'v1.0.7', 35 | 'version' => '1.0.7.0', 36 | 'aliases' => 37 | array ( 38 | ), 39 | 'reference' => '7f81b0c3bb0a9f4200aef62a54d3e2c04d91a605', 40 | ), 41 | ), 42 | ); 43 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/composer/platform_check.php: -------------------------------------------------------------------------------- 1 | = 70100)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fbett/le_acme2", 3 | "description": "Letsencrypt PHP ACME v2 client", 4 | "homepage": "https://github.com/fbett/le-acme2-php", 5 | "version": "1.5.6", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Fabian Bett", 10 | "homepage": "https://www.bett-ingenieure.de", 11 | "role": "Developer" 12 | } 13 | ], 14 | "autoload": { 15 | "psr-0": { 16 | "LE_ACME2": "src/" 17 | } 18 | }, 19 | "require": { 20 | "php": ">=7.3", 21 | "ext-curl": "*", 22 | "ext-openssl": "*", 23 | "ext-json": "*" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | ./src/LE_ACME2 18 | 19 | 20 | 21 | 22 | ./src/LE_ACME2Tests 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Authorizer/AbstractDNSWriter.php: -------------------------------------------------------------------------------- 1 | getKeyDirectoryPath(); 13 | } 14 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Cache/NewNonceResponse.php: -------------------------------------------------------------------------------- 1 | _index, $this->_responses)) { 28 | return $this->_responses[$this->_index]; 29 | } 30 | $this->_responses[$this->_index] = null; 31 | 32 | $request = new Request\GetNewNonce(); 33 | $response = $request->getResponse(); 34 | $this->set($response); 35 | 36 | return $response; 37 | } 38 | 39 | public function set(Response\GetNewNonce $response) : void { 40 | $this->_responses[$this->_index] = $response; 41 | } 42 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Connector/RawResponse.php: -------------------------------------------------------------------------------- 1 | request = $method . ' ' . $url; 25 | 26 | $this->header = array_map(function($line) { 27 | return trim($line); 28 | }, explode("\n", $header)); 29 | 30 | $this->body = $body_json === null ? $body : $body_json; 31 | } 32 | 33 | public function toString() : string { 34 | 35 | return serialize([ 36 | 'request' => $this->request, 37 | 'header' => $this->header, 38 | 'body' => $this->body, 39 | ]); 40 | } 41 | 42 | public static function getFromString(string $string) : self { 43 | 44 | $array = unserialize($string); 45 | 46 | $rawResponse = new self(); 47 | 48 | $rawResponse->request = $array['request']; 49 | $rawResponse->header = $array['header']; 50 | $rawResponse->body = $array['body']; 51 | 52 | return $rawResponse; 53 | } 54 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Exception/AbstractException.php: -------------------------------------------------------------------------------- 1 | add( 13 | Utilities\Logger::LEVEL_DEBUG, 14 | 'Exception "' . get_called_class() . '" thrown ' 15 | ); 16 | 17 | parent::__construct($message); 18 | } 19 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Exception/AuthorizationInvalid.php: -------------------------------------------------------------------------------- 1 | _rawResponse = $rawResponse; 16 | $this->_responseStatus = $responseStatus; 17 | 18 | if($responseStatus === '') { 19 | $responseStatus = 'Unknown response status'; 20 | } 21 | 22 | if(isset($this->_rawResponse->body['type'])) { 23 | $responseStatus = $this->_rawResponse->body['type']; 24 | } 25 | 26 | if(isset($this->_rawResponse->body['detail'])) { 27 | $responseStatus .= ' - ' . $this->_rawResponse->body['detail']; 28 | } 29 | 30 | parent::__construct('Invalid response received: ' . $responseStatus); 31 | } 32 | 33 | public function getRawResponse() : RawResponse { 34 | return $this->_rawResponse; 35 | } 36 | 37 | public function getResponseStatus() : ?string { 38 | return $this->_responseStatus; 39 | } 40 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Exception/OpenSSLException.php: -------------------------------------------------------------------------------- 1 | 'deactivated', 16 | ]; 17 | } 18 | 19 | /** 20 | * @return Response\AbstractResponse|Response\Account\Deactivate 21 | * @throws Exception\InvalidResponse 22 | * @throws Exception\RateLimitReached 23 | */ 24 | public function getResponse() : Response\AbstractResponse { 25 | 26 | return new Response\Account\Deactivate($this->_getRawResponse()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Request/Account/Get.php: -------------------------------------------------------------------------------- 1 | _account = $account; 22 | } 23 | 24 | /** 25 | * @return Response\AbstractResponse|Response\Account\Get 26 | * @throws Exception\InvalidResponse 27 | * @throws Exception\RateLimitReached 28 | */ 29 | public function getResponse() : Response\AbstractResponse { 30 | 31 | $payload = [ 32 | 'onlyReturnExisting' => true, 33 | ]; 34 | 35 | $jwk = Utilities\RequestSigner::JWKString( 36 | $payload, 37 | Cache\DirectoryResponse::getInstance()->get()->getNewAccount(), 38 | Cache\NewNonceResponse::getInstance()->get()->getNonce(), 39 | $this->_account->getKeyDirectoryPath() 40 | ); 41 | 42 | $result = Connector\Connector::getInstance()->request( 43 | Connector\Connector::METHOD_POST, 44 | Cache\DirectoryResponse::getInstance()->get()->getNewAccount(), 45 | $jwk 46 | ); 47 | 48 | return new Response\Account\Get($result); 49 | } 50 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Request/Account/GetData.php: -------------------------------------------------------------------------------- 1 | _getRawResponse()); 25 | } 26 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Request/Account/Update.php: -------------------------------------------------------------------------------- 1 | _newEmail = $newEmail; 21 | } 22 | 23 | protected function _getPayload() : array { 24 | 25 | return [ 26 | 'contact' => $this->_buildContactPayload($this->_newEmail), 27 | ]; 28 | } 29 | 30 | /** 31 | * @return Response\AbstractResponse|Response\Account\Update 32 | * @throws Exception\InvalidResponse 33 | * @throws Exception\RateLimitReached 34 | */ 35 | public function getResponse() : Response\AbstractResponse { 36 | return new Response\Account\Update($this->_getRawResponse()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Request/GetDirectory.php: -------------------------------------------------------------------------------- 1 | request( 23 | Connector::METHOD_GET, 24 | $connector->getBaseURL() . '/directory' 25 | ); 26 | return new Response\GetDirectory($result); 27 | } 28 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Request/GetNewNonce.php: -------------------------------------------------------------------------------- 1 | request( 22 | Connector\Connector::METHOD_HEAD, 23 | Cache\DirectoryResponse::getInstance()->get()->getNewNonce() 24 | ); 25 | 26 | return new Response\GetNewNonce($result); 27 | } 28 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/Account/AbstractAccount.php: -------------------------------------------------------------------------------- 1 | _preg_match_headerLine($this->_pattern_header_location); 16 | return trim($matches[1]); 17 | } 18 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/Account/AbstractLocation.php: -------------------------------------------------------------------------------- 1 | _raw->body['key']; 12 | } 13 | 14 | public function getContact() : string { 15 | return $this->_raw->body['contact']; 16 | } 17 | 18 | public function getAgreement() : string { 19 | return $this->_raw->body['agreement']; 20 | } 21 | 22 | public function getInitialIP() : string { 23 | return $this->_raw->body['initialIp']; 24 | } 25 | 26 | public function getCreatedAt() : string { 27 | return $this->_raw->body['createdAt']; 28 | } 29 | 30 | public function getStatus() : string { 31 | return $this->_raw->body['status']; 32 | } 33 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/Account/ChangeKeys.php: -------------------------------------------------------------------------------- 1 | _preg_match_headerLine('/^HTTP\/.* 404/i') !== null) { 31 | throw new Exception\ExpiredAuthorization(); 32 | } 33 | 34 | return parent::_isValid(); 35 | } 36 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/Authorization/Get.php: -------------------------------------------------------------------------------- 1 | _raw->body['identifier']['type'], $this->_raw->body['identifier']['value']); 12 | } 13 | 14 | public function getStatus() : string { 15 | return $this->_raw->body['status']; 16 | } 17 | 18 | public function getExpires() : string { 19 | return $this->_raw->body['expires']; 20 | } 21 | 22 | public function getChallenges() : array { 23 | return $this->_raw->body['challenges']; 24 | } 25 | 26 | /** 27 | * @param $type 28 | * @return Struct\Challenge 29 | */ 30 | public function getChallenge(string $type) : Struct\Challenge { 31 | 32 | foreach($this->getChallenges() as $challenge) { 33 | 34 | if($type == $challenge['type']) 35 | return new Struct\Challenge($challenge['type'], $challenge['status'], $challenge['url'], $challenge['token']); 36 | } 37 | throw new \RuntimeException('No challenge found with given type'); 38 | } 39 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/Authorization/Start.php: -------------------------------------------------------------------------------- 1 | type = $type; 21 | $this->status = $status; 22 | $this->url = $url; 23 | $this->token = $token; 24 | } 25 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/Authorization/Struct/Identifier.php: -------------------------------------------------------------------------------- 1 | type = $type; 14 | $this->value = $value; 15 | } 16 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/GetDirectory.php: -------------------------------------------------------------------------------- 1 | _raw->body['keyChange']; 10 | } 11 | 12 | public function getNewAccount() : string { 13 | return $this->_raw->body['newAccount']; 14 | } 15 | 16 | public function getNewNonce() : string { 17 | return $this->_raw->body['newNonce']; 18 | } 19 | 20 | public function getNewOrder() : string { 21 | return $this->_raw->body['newOrder']; 22 | } 23 | 24 | public function getRevokeCert() : string { 25 | return $this->_raw->body['revokeCert']; 26 | } 27 | 28 | public function getTermsOfService() : string { 29 | return $this->_raw->body['meta']['termsOfService']; 30 | } 31 | 32 | public function getWebsite() : string { 33 | return $this->_raw->body['meta']['website']; 34 | } 35 | 36 | public function getCaaIdentities() : string { 37 | return $this->_raw->body['meta']['caaIdentities']; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/GetNewNonce.php: -------------------------------------------------------------------------------- 1 | _preg_match_headerLine($this->_pattern) !== null; 12 | } 13 | 14 | public function getNonce() : string { 15 | 16 | $matches = $this->_preg_match_headerLine($this->_pattern); 17 | return trim($matches[1]); 18 | } 19 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/Order/Create.php: -------------------------------------------------------------------------------- 1 | header[] = 'Location: ' . $orderURL; 24 | 25 | parent::__construct($raw); 26 | } 27 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Response/Order/RevokeCertificate.php: -------------------------------------------------------------------------------- 1 | path = $path; 17 | $this->private = $private; 18 | $this->certificate = $certificate; 19 | $this->intermediate = $intermediate; 20 | $this->expireTime = $expireTime; 21 | } 22 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Struct/ChallengeAuthorizationKey.php: -------------------------------------------------------------------------------- 1 | _account = $account; 15 | } 16 | 17 | public function get(string $token) : string { 18 | return $token . '.' . $this->_getDigest(); 19 | } 20 | 21 | public function getEncoded(string $token) : string { 22 | return Utilities\Base64::UrlSafeEncode( 23 | hash('sha256', $this->get($token), true) 24 | ); 25 | } 26 | 27 | private function _getDigest() : string { 28 | 29 | $privateKey = openssl_pkey_get_private(file_get_contents($this->_account->getKeyDirectoryPath() . 'private.pem')); 30 | $details = openssl_pkey_get_details($privateKey); 31 | 32 | $header = array( 33 | "e" => Utilities\Base64::UrlSafeEncode($details["rsa"]["e"]), 34 | "kty" => "RSA", 35 | "n" => Utilities\Base64::UrlSafeEncode($details["rsa"]["n"]) 36 | 37 | ); 38 | return Utilities\Base64::UrlSafeEncode(hash('sha256', json_encode($header), true)); 39 | } 40 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2/Utilities/Base64.php: -------------------------------------------------------------------------------- 1 | useStagingServer(true); 14 | } 15 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2Tests/Authorizer/HTTPTest.php: -------------------------------------------------------------------------------- 1 | _directoryPath = TestHelper::getInstance()->getTempPath() . 'acme-challenges/'; 19 | } 20 | 21 | public function testNonExistingDirectoryPath() { 22 | 23 | $this->assertTrue(\LE_ACME2\Authorizer\HTTP::getDirectoryPath() === null); 24 | 25 | $this->expectException(\RuntimeException::class); 26 | \LE_ACME2\Authorizer\HTTP::setDirectoryPath(TestHelper::getInstance()->getNonExistingPath()); 27 | } 28 | 29 | public function testDirectoryPath() { 30 | 31 | if(!file_exists($this->_directoryPath)) { 32 | mkdir($this->_directoryPath); 33 | } 34 | 35 | \LE_ACME2\Authorizer\HTTP::setDirectoryPath($this->_directoryPath); 36 | 37 | $this->assertTrue( 38 | \LE_ACME2\Authorizer\HTTP::getDirectoryPath() === $this->_directoryPath 39 | ); 40 | } 41 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/fbett/le_acme2/src/LE_ACME2Tests/TestHelper.php: -------------------------------------------------------------------------------- 1 | _tempPath = $projectPath . 'temp/'; 18 | if( !file_exists($this->_tempPath) ) { 19 | mkdir($this->_tempPath); 20 | } 21 | 22 | $this->_nonExistingPath = $this->getTempPath() . 'should-not-exist/'; 23 | } 24 | 25 | public function getTempPath() : string { 26 | return $this->_tempPath; 27 | } 28 | 29 | public function getNonExistingPath() : string { 30 | return $this->_nonExistingPath; 31 | } 32 | 33 | private $_skipAccountModificationTests = false; 34 | 35 | public function setSkipAccountModificationTests(bool $value) : void { 36 | $this->_skipAccountModificationTests = $value; 37 | } 38 | 39 | public function shouldSkipAccountModificationTests() : bool { 40 | return $this->_skipAccountModificationTests; 41 | } 42 | } -------------------------------------------------------------------------------- /lets-encrypt/vendor/index.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: recommended 2 | 3 | disabled: 4 | - align_double_arrow 5 | - phpdoc_align 6 | - blank_line_after_opening_tag 7 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/.travis.yml: -------------------------------------------------------------------------------- 1 | services: docker 2 | 3 | script: 4 | - docker-compose run tests 5 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.3-cli 2 | 3 | RUN apt-get update \ 4 | && apt-get install -y unzip \ 5 | && docker-php-ext-install pcntl \ 6 | && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer 7 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 1999-2020. Plesk International GmbH. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plesk/api-php-lib", 3 | "type": "library", 4 | "description": "PHP object-oriented library for Plesk XML-RPC API", 5 | "license": "Apache-2.0", 6 | "authors": [ 7 | { 8 | "name": "Alexei Yuzhakov", 9 | "email": "sibprogrammer@gmail.com" 10 | }, 11 | { 12 | "name": "Plesk International GmbH.", 13 | "email": "plesk-dev-leads@plesk.com" 14 | } 15 | ], 16 | "require": { 17 | "php": "^7.3", 18 | "ext-curl": "*", 19 | "ext-xml": "*", 20 | "ext-simplexml": "*" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit": "^9", 24 | "spatie/phpunit-watcher": "^1.22" 25 | }, 26 | "config": { 27 | "process-timeout": 0 28 | }, 29 | "scripts": { 30 | "test": "phpunit", 31 | "test:watch": "phpunit-watcher watch" 32 | }, 33 | "autoload": { 34 | "psr-4": { 35 | "PleskX\\": "src/" 36 | } 37 | }, 38 | "autoload-dev": { 39 | "psr-4": { 40 | "PleskXTest\\": "tests/" 41 | } 42 | }, 43 | "extra": { 44 | "branch-alias": { 45 | "dev-master": "2.0.x-dev" 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | plesk: 4 | image: plesk/plesk 5 | logging: 6 | driver: none 7 | ports: 8 | ["8443:8443"] 9 | tests: 10 | build: . 11 | environment: 12 | REMOTE_URL: https://plesk:8443 13 | REMOTE_PASSWORD: changeme1Q** 14 | command: bash -c "cd /opt/api-php-lib && composer install && ./wait-for-plesk.sh && composer test -- --testdox" 15 | depends_on: 16 | - plesk 17 | links: 18 | - plesk 19 | volumes: 20 | - .:/opt/api-php-lib 21 | 22 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/phpunit-watcher.yml: -------------------------------------------------------------------------------- 1 | phpunit: 2 | arguments: '--stop-on-failure' 3 | timeout: 0 4 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | ./tests 11 | 12 | 13 | 14 | 15 | 16 | ./src 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Client/Exception.php: -------------------------------------------------------------------------------- 1 | _login = $login; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Operator/EventLog.php: -------------------------------------------------------------------------------- 1 | request('get'); 19 | 20 | foreach ($response->event as $eventInfo) { 21 | $records[] = new Struct\Event($eventInfo); 22 | } 23 | 24 | return $records; 25 | } 26 | 27 | /** 28 | * @return Struct\DetailedEvent[] 29 | */ 30 | public function getDetailedLog() 31 | { 32 | $records = []; 33 | $response = $this->request('get_events'); 34 | 35 | foreach ($response->event as $eventInfo) { 36 | $records[] = new Struct\DetailedEvent($eventInfo); 37 | } 38 | 39 | return $records; 40 | } 41 | 42 | /** 43 | * @return int 44 | */ 45 | public function getLastId() 46 | { 47 | return (int) $this->request('get-last-id')->getValue('id'); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Operator/Ip.php: -------------------------------------------------------------------------------- 1 | _client->getPacket(); 17 | $packet->addChild($this->_wrapperTag)->addChild('get'); 18 | $response = $this->_client->request($packet); 19 | 20 | foreach ($response->addresses->ip_info as $ipInfo) { 21 | $ips[] = new Struct\Info($ipInfo); 22 | } 23 | 24 | return $ips; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Operator/Locale.php: -------------------------------------------------------------------------------- 1 | _client->getPacket(); 19 | $filter = $packet->addChild($this->_wrapperTag)->addChild('get')->addChild('filter'); 20 | 21 | if (!is_null($id)) { 22 | $filter->addChild('id', $id); 23 | } 24 | 25 | $response = $this->_client->request($packet, \PleskX\Api\Client::RESPONSE_FULL); 26 | 27 | foreach ($response->locale->get->result as $localeInfo) { 28 | $locales[(string) $localeInfo->info->id] = new Struct\Info($localeInfo->info); 29 | } 30 | 31 | return !is_null($id) ? reset($locales) : $locales; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Operator/Session.php: -------------------------------------------------------------------------------- 1 | request('get'); 17 | 18 | foreach ($response->session as $sessionInfo) { 19 | $sessions[(string) $sessionInfo->id] = new Struct\Info($sessionInfo); 20 | } 21 | 22 | return $sessions; 23 | } 24 | 25 | /** 26 | * @param string $sessionId 27 | * 28 | * @return bool 29 | */ 30 | public function terminate($sessionId) 31 | { 32 | $response = $this->request("terminate.session-id=$sessionId"); 33 | 34 | return 'ok' === (string) $response->status; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/Certificate/Info.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 17 | ['csr' => 'request'], 18 | ['pvt' => 'privateKey'], 19 | ]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/Dns/Info.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 32 | 'id', 33 | 'site-id', 34 | 'site-alias-id', 35 | 'type', 36 | 'host', 37 | 'value', 38 | 'opt', 39 | ]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/EventLog/DetailedEvent.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 32 | 'id', 33 | 'type', 34 | 'time', 35 | 'class', 36 | ['obj_id' => 'objectId'], 37 | 'user', 38 | 'host', 39 | ]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/EventLog/Event.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 23 | 'type', 24 | 'time', 25 | 'class', 26 | 'id', 27 | ]); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/Locale/Info.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 20 | 'id', 21 | ['lang' => 'language'], 22 | 'country', 23 | ]); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/PhpHandler/Info.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 43 | 'id', 44 | 'display-name', 45 | 'full-version', 46 | 'version', 47 | 'type', 48 | 'path', 49 | 'clipath', 50 | 'phpini', 51 | 'custom', 52 | 'handler-status', 53 | ]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/SecretKey/Info.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 23 | 'key', 24 | 'ip_address', 25 | 'description', 26 | 'login', 27 | ]); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/Session/Info.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 29 | 'id', 30 | 'type', 31 | 'ip-address', 32 | 'login', 33 | 'login-time', 34 | 'idle', 35 | ]); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/Site/GeneralInfo.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 26 | 'name', 27 | 'ascii-name', 28 | 'status', 29 | 'guid', 30 | 'description', 31 | ]); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/Site/HostingInfo.php: -------------------------------------------------------------------------------- 1 | vrt_hst->property as $property) { 17 | $this->properties[(string) $property->name] = (string) $property->value; 18 | } 19 | $this->_initScalarProperties($apiResponse->vrt_hst, [ 20 | 'ip_address', 21 | ]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/Site/Info.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 17 | 'id', 18 | 'guid', 19 | ]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/SiteAlias/GeneralInfo.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 20 | 'name', 21 | 'ascii-name', 22 | 'status', 23 | ]); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/Struct/SiteAlias/Info.php: -------------------------------------------------------------------------------- 1 | _initScalarProperties($apiResponse, [ 17 | 'id', 18 | 'status', 19 | ]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/src/Api/XmlResponse.php: -------------------------------------------------------------------------------- 1 | xpath('//'.$node)[0]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/api-php-lib/wait-for-plesk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### Copyright 1999-2020. Plesk International GmbH. 3 | 4 | while : ; do 5 | curl -ksL https://plesk:8443/ | grep "Plesk" > /dev/null 6 | [ $? -eq 0 ] && break 7 | sleep 5 8 | done 9 | -------------------------------------------------------------------------------- /lets-encrypt/vendor/plesk/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /mailer/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/mailer/.DS_Store -------------------------------------------------------------------------------- /mailer/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /mailer/templates/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /modal/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/modal/.DS_Store -------------------------------------------------------------------------------- /modal/build/index.d4bca8705bbc6e3e5777.asset.php: -------------------------------------------------------------------------------- 1 | <?php return array('dependencies' => array('react', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'd4bca8705bbc6e3e5777'); 2 | -------------------------------------------------------------------------------- /modal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "really-simple-ssl-modal", 3 | "version": "1.0.1", 4 | "description": "Executes the modal functionality for the plugins page for really-simple-ssl", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "wp-scripts start", 8 | "build": "set \"INLINE_RUNTIME_CHUNK=false\" && wp-scripts build" 9 | }, 10 | "author": "Really Simple Plugins", 11 | "license": "GPL-2.0-only", 12 | "devDependencies": { 13 | "@wordpress/scripts": "^26.12.0", 14 | "sass": "^1.68.0", 15 | "sass-loader": "^13.3.2", 16 | "webpack": "^5.88.2", 17 | "webpack-cli": "^5.1.4" 18 | }, 19 | "dependencies": { 20 | "css-loader": "^6.8.1", 21 | "style-loader": "^3.3.3", 22 | "styled-components": "^6.0.8" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /modal/src/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | render, createRoot 3 | } from '@wordpress/element'; 4 | import DeactivationModal from "./components/DeactivationModal/DeactivationModal"; 5 | document.addEventListener( 'DOMContentLoaded', () => { 6 | 7 | const container = document.getElementById( 'rsssl-modal-root' ); 8 | if ( container ) { 9 | if ( createRoot ) { 10 | createRoot( container ).render( <DeactivationModal/> ); 11 | } else { 12 | render( <DeactivationModal/>, container ); 13 | } 14 | } 15 | }); -------------------------------------------------------------------------------- /modal/webpack.config.js: -------------------------------------------------------------------------------- 1 | const defaultConfig = require("@wordpress/scripts/config/webpack.config"); 2 | 3 | module.exports = { 4 | ...defaultConfig, 5 | output: { 6 | ...defaultConfig.output, 7 | filename: '[name].[contenthash].js', 8 | chunkFilename: '[name].[contenthash].js', 9 | } 10 | }; -------------------------------------------------------------------------------- /onboarding/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /placeholders/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /progress/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | declare(strict_types=1); 4 | 5 | use Rector\Config\RectorConfig; 6 | use Rector\Transform\Rector\ClassMethod\ReturnTypeWillChangeRector; 7 | 8 | return RectorConfig::configure() 9 | ->withPaths([ 10 | // __DIR__ . '/assets', 11 | // __DIR__ . '/automation', 12 | // __DIR__ . '/languages', 13 | // __DIR__ . '/lets-encrypt', 14 | // __DIR__ . '/lib', 15 | // __DIR__ . '/mailer', 16 | // __DIR__ . '/modal', 17 | // __DIR__ . '/onboarding', 18 | // __DIR__ . '/placeholders', 19 | __DIR__ . '/pro/security/wordpress/two-fa', 20 | // __DIR__ . '/progress', 21 | __DIR__ . '/security/wordpress/two-fa', 22 | // __DIR__ . '/settings', 23 | // __DIR__ . '/tests', 24 | // __DIR__ . '/upgrade', 25 | ]) 26 | // uncomment to reach your current PHP version 27 | // ->withPhpSets() 28 | ->withTypeCoverageLevel(0) 29 | ->withImportNames(true) 30 | // ->withPhp74Sets() 31 | ->withDeadCodeLevel(1) 32 | ->withCodeQualityLevel(1) 33 | ->withRules([ 34 | ReturnTypeWillChangeRector::class, 35 | \Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector::class, 36 | 37 | ]) 38 | ; 39 | -------------------------------------------------------------------------------- /security.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | The security of our software products is essential to us and our customers. In spite of our care, procedures and best efforts it is possible that there are vulnerabilities in our software products. If you find any, please tell us as soon as possible so we can fix them. 4 | 5 | ## Reporting a Vulnerability 6 | 7 | To report a security issue, please [email us](mailto:security@really-simple-plugins.com) with a description of the issue, the steps you took to create the issue, affected versions, and, if known, mitigations for the issue. 8 | Please read our [Coordinated Vulnerability Disclosure Policy](https://really-simple-plugins.com/security) before reporting any vulnerabilities. -------------------------------------------------------------------------------- /security/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. 2 | -------------------------------------------------------------------------------- /security/server/disable-indexing.php: -------------------------------------------------------------------------------- 1 | <?php 2 | defined( 'ABSPATH' ) or die(); 3 | if ( rsssl_is_in_deactivation_list('disable-indexing') ){ 4 | rsssl_remove_from_deactivation_list('disable-indexing'); 5 | } 6 | 7 | /** 8 | * Disable indexing 9 | * @param array $rules 10 | * @return [] 11 | */ 12 | 13 | function rsssl_disable_indexing_rules( $rules ) { 14 | $rules[] = ['rules' => "\n" . 'Options -Indexes', 'identifier' => 'Options -Indexes']; 15 | return $rules; 16 | } 17 | add_filter('rsssl_htaccess_security_rules', 'rsssl_disable_indexing_rules'); 18 | 19 | /** 20 | * Dropped suggestions for indexing in NGINX as indexing in NGINX is by default disabled. 21 | */ 22 | -------------------------------------------------------------------------------- /security/server/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. 2 | -------------------------------------------------------------------------------- /security/tests/code-execution.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Test file for Really Simple Security to check if uploads directory has code execution permissions 4 | * 5 | */ 6 | 7 | echo "RSSSL CODE EXECUTION MARKER"; 8 | -------------------------------------------------------------------------------- /security/tests/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /security/wordpress/disable-xmlrpc.php: -------------------------------------------------------------------------------- 1 | <?php 2 | defined( 'ABSPATH' ) or die( "you do not have access to this page!" ); 3 | 4 | /** 5 | * Disable XMLRPC when this integration is activated 6 | */ 7 | 8 | add_filter('xmlrpc_enabled', '__return_false'); 9 | /** 10 | * Remove html link 11 | */ 12 | remove_action( 'wp_head', 'rsd_link' ); 13 | /** 14 | * stop all requests to xmlrpc.php for RSD per XML-RPC: 15 | */ 16 | if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) 17 | exit; 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /security/wordpress/file-editing.php: -------------------------------------------------------------------------------- 1 | <?php 2 | defined( 'ABSPATH' ) or die(); 3 | 4 | /** 5 | * @return void 6 | * 7 | * Disable file editing 8 | */ 9 | function rsssl_disable_file_editing() { 10 | if ( ! defined('DISALLOW_FILE_EDIT' ) ) { 11 | define('DISALLOW_FILE_EDIT', true ); 12 | } 13 | } 14 | add_action("init", "rsssl_disable_file_editing"); 15 | 16 | 17 | /** 18 | * Username 'admin' changed notice 19 | * @return array 20 | */ 21 | function rsssl_disable_file_editing_notice( $notices ) { 22 | $notices['disallow_file_edit_false'] = array( 23 | 'condition' => ['rsssl_file_editing_defined_but_disabled'], 24 | 'callback' => '_true_', 25 | 'score' => 5, 26 | 'output' => array( 27 | 'true' => array( 28 | 'msg' => __("The DISALLOW_FILE_EDIT constant is defined and set to false. You can remove it from your wp-config.php.", "really-simple-ssl"), 29 | 'icon' => 'open', 30 | 'dismissible' => true, 31 | 'url' => 'disallow_file_edit-defined-set-to-false' 32 | ), 33 | ), 34 | ); 35 | return $notices; 36 | } 37 | add_filter('rsssl_notices', 'rsssl_disable_file_editing_notice'); 38 | 39 | /** 40 | * Check if the constant is defined, AND set to false. In that case the plugin cannot override it anymore 41 | * @return bool 42 | */ 43 | function rsssl_file_editing_defined_but_disabled(){ 44 | return defined( 'DISALLOW_FILE_EDIT' ) && ! DISALLOW_FILE_EDIT; 45 | } -------------------------------------------------------------------------------- /security/wordpress/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /security/wordpress/prevent-login-info-leakage.php: -------------------------------------------------------------------------------- 1 | <?php 2 | defined('ABSPATH') or die(); 3 | /** 4 | * Override default login error message 5 | * @return string|void 6 | **/ 7 | function rsssl_no_wp_login_errors() 8 | { 9 | return __("Invalid login details.", "really-simple-ssl"); 10 | } 11 | add_filter( 'login_errors', 'rsssl_no_wp_login_errors' ); 12 | 13 | /** 14 | * Hide feedback entirely on password reset (no filter available). 15 | * 16 | * @return void 17 | * 18 | */ 19 | function rsssl_hide_pw_reset_error() { 20 | ?> 21 | <style> 22 | .login-action-lostpassword #login_error{ 23 | display: none; 24 | } 25 | </style> 26 | <?php 27 | } 28 | add_action( 'login_enqueue_scripts', 'rsssl_hide_pw_reset_error' ); 29 | 30 | /** 31 | * 32 | * Clear username when username is valid but password is incorrect 33 | * 34 | * @return void 35 | */ 36 | function rsssl_clear_username_on_correct_username() { 37 | ?> 38 | <script> 39 | if ( document.getElementById('login_error') ) { 40 | document.getElementById('user_login').value = ''; 41 | } 42 | </script> 43 | <?php 44 | } 45 | add_action( 'login_footer', 'rsssl_clear_username_on_correct_username' ); 46 | -------------------------------------------------------------------------------- /security/wordpress/two-fa/assets/css/profile-settings.scss: -------------------------------------------------------------------------------- 1 | #two-factor-qr-code { 2 | display: flex; /* Enables Flexbox */ 3 | justify-content: left; /* Centers horizontally */ 4 | align-items: center; /* Centers vertically */ 5 | width: 100%; 6 | min-height: 100%; 7 | } 8 | 9 | #qr-code-container { 10 | margin-bottom: 20px; 11 | position: relative; 12 | text-align: center; 13 | //right: 0; 14 | } 15 | 16 | #two-factor-totp-authcode { 17 | width: 100%; 18 | } 19 | tr.rsssl_verify_email { 20 | display: none; 21 | } 22 | .error { 23 | color: red; 24 | margin-top: -5px; 25 | } 26 | 27 | span.rsssl-backup-codes { 28 | padding: 5px; 29 | background: #fbebed; 30 | border-radius: 8px; 31 | box-shadow: rgba(0,0,0,0.1) 0 4px 6px -1px; 32 | } 33 | 34 | .input { 35 | margin-bottom: 5px !important; 36 | } 37 | 38 | #totp-key { 39 | cursor: pointer; 40 | display: flex; /* Enables Flexbox */ 41 | justify-content: center; /* Centers horizontally */ 42 | align-items: center; /* Centers vertically */ 43 | } 44 | 45 | table.rsssl-table-two-fa { 46 | padding-bottom: 20px; 47 | } 48 | 49 | .rsssl-methods-tag { 50 | padding: 2px 5px; 51 | border: 1px solid #000; 52 | color: #000; 53 | margin-left: 5px; 54 | background: dimgrey; 55 | &.active { 56 | background: darkgreen; 57 | color: #fff; 58 | } 59 | } -------------------------------------------------------------------------------- /security/wordpress/two-fa/assets/css/two-fa.scss: -------------------------------------------------------------------------------- 1 | @import "profile-settings.scss"; 2 | @import "two-fa-onboarding.scss"; -------------------------------------------------------------------------------- /security/wordpress/two-fa/contracts/interface-rsssl-has-processing-interface.php: -------------------------------------------------------------------------------- 1 | <?php 2 | namespace RSSSL\Security\WordPress\Two_Fa\Contracts; 3 | 4 | use RSSSL\Security\WordPress\Two_Fa\Models\Rsssl_Two_Fa_User_Collection; 5 | 6 | interface Rsssl_Has_Processing_Interface 7 | { 8 | /** 9 | * Processes a collection of Data Transfer Objects. 10 | * @return Rsssl_Two_Fa_User_Collection 11 | */ 12 | public function processBatch(array $args, string $switchValue): Rsssl_Two_Fa_User_Collection; 13 | } -------------------------------------------------------------------------------- /security/wordpress/two-fa/contracts/interface-rsssl-two-fa-user-query-builder-interface.php: -------------------------------------------------------------------------------- 1 | <?php 2 | namespace RSSSL\Security\WordPress\Two_Fa\Contracts; 3 | 4 | use RSSSL\Security\WordPress\Two_Fa\Models\Rsssl_Two_FA_Data_Parameters; 5 | 6 | interface Rsssl_Two_Fa_User_Query_Builder_Interface { 7 | /** 8 | * Build query args based on data parameters. 9 | * 10 | * @return array 11 | */ 12 | public function buildQueryArgs(Rsssl_Two_FA_Data_Parameters $params): array; 13 | 14 | public function addDisabledConditionToArgs(array $args): array; 15 | 16 | public function addOpenStatusConditionToArgs(array $args): array; 17 | 18 | public function addNearingExpiryCondition(array $args, int $daysThreshold, int $reminderBeforeClosingPeriod = 3): array; 19 | 20 | public function addForcedRolesConditionToArgs(array $args, array $getForcedRoles): array; 21 | } 22 | -------------------------------------------------------------------------------- /security/wordpress/two-fa/contracts/interface-rsssl-two-fa-user-repository-interface.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | namespace RSSSL\Security\WordPress\Two_Fa\Contracts; 4 | 5 | use RSSSL\Security\WordPress\Two_Fa\Models\Rsssl_Two_FA_Data_Parameters; 6 | use RSSSL\Security\WordPress\Two_Fa\Models\Rsssl_Two_Fa_User_Collection; 7 | 8 | interface Rsssl_Two_Fa_User_Repository_Interface { 9 | /** 10 | * Retrieve two-factor authentication users based on data parameters. 11 | * 12 | * @return Rsssl_Two_Fa_User_Collection 13 | */ 14 | public function getTwoFaUsers(Rsssl_Two_FA_Data_Parameters $params): Rsssl_Two_Fa_User_Collection; 15 | 16 | 17 | /** 18 | * Needed for getting all the expired users. 19 | * 20 | * @return Rsssl_Two_Fa_User_Collection 21 | */ 22 | public function geTwoFAExpiredUsers(Rsssl_Two_FA_Data_Parameters $params): Rsssl_Two_Fa_User_Collection; 23 | 24 | /** 25 | * Retrieve forced two-factor authentication users with open status. 26 | * 27 | * @return Rsssl_Two_Fa_User_Collection 28 | */ 29 | public function getForcedTwoFaUsersWithOpenStatus(Rsssl_Two_FA_Data_Parameters $params): Rsssl_Two_Fa_User_Collection; 30 | 31 | } -------------------------------------------------------------------------------- /security/wordpress/two-fa/models/class-rsssl-two-fa-user-collection.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | namespace RSSSL\Security\WordPress\Two_Fa\Models; 4 | 5 | class Rsssl_Two_Fa_User_Collection 6 | { 7 | 8 | /** 9 | * An array to hold TwoFaUser objects. 10 | * 11 | * @var Rsssl_Two_FA_user[] 12 | */ 13 | private array $users = []; 14 | 15 | /** 16 | * The total number of records (useful for pagination). 17 | * 18 | * @var int 19 | */ 20 | private int $totalRecords = 0; 21 | 22 | /** 23 | * Add a TwoFaUser to the collection. 24 | */ 25 | public function add(Rsssl_Two_FA_user $user): void 26 | { 27 | $this->users[] = $user; 28 | } 29 | 30 | /** 31 | * Retrieve all TwoFaUser objects in the collection. 32 | * 33 | * @return Rsssl_Two_FA_user[] 34 | */ 35 | public function getUsers(): array 36 | { 37 | return $this->users; 38 | } 39 | 40 | /** 41 | * Set the total number of records. 42 | */ 43 | public function setTotalRecords(int $totalRecords): void 44 | { 45 | $this->totalRecords = $totalRecords; 46 | } 47 | 48 | /** 49 | * Get the total number of records. 50 | * 51 | * @return int 52 | */ 53 | public function getTotalRecords(): int 54 | { 55 | return $this->totalRecords; 56 | } 57 | } -------------------------------------------------------------------------------- /security/wordpress/two-fa/providers/class-rsssl-provider-loader-free.php: -------------------------------------------------------------------------------- 1 | <?php 2 | namespace RSSSL\Security\WordPress\Two_Fa\Providers; 3 | 4 | class Rsssl_Provider_Loader_Free extends Rsssl_Provider_Loader 5 | { 6 | public static function get_providers(): array { 7 | return parent::get_providers(); 8 | } 9 | } -------------------------------------------------------------------------------- /security/wordpress/two-fa/providers/interface-rsssl-two-factor-provider-interface.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Holds the request parameters for a specific action. 4 | * 5 | * @package REALLY_SIMPLE_SSL 6 | */ 7 | 8 | namespace RSSSL\Security\WordPress\Two_Fa\Providers; 9 | 10 | use WP_User; 11 | 12 | /** 13 | * Check if a user is forced. 14 | * 15 | * @param WP_User $user The user to check. 16 | * 17 | * @return bool True if the user is forced, false otherwise. 18 | */ 19 | interface Rsssl_Two_Factor_Provider_Interface { 20 | /** 21 | * Check if a user is forced. 22 | * 23 | * @param WP_User $user The user to check. 24 | * 25 | * @return bool True if the user is forced, false otherwise. 26 | */ 27 | public static function is_forced( WP_User $user ): bool; 28 | 29 | /** 30 | * Check if a method is enabled within the roles of the user. 31 | * 32 | * @param WP_User $user The user to check. 33 | * 34 | * @return bool True if the user is enabled, false otherwise. 35 | */ 36 | public static function is_enabled( WP_User $user ): bool; 37 | 38 | public static function is_optional( WP_User $user ): bool; 39 | 40 | public static function is_configured( WP_User $user ): bool; 41 | } 42 | -------------------------------------------------------------------------------- /security/wordpress/two-fa/services/class-rsssl-two-fa-status-service.php: -------------------------------------------------------------------------------- 1 | <?php 2 | namespace RSSSL\Security\WordPress\Two_Fa\Services; 3 | 4 | class Rsssl_Two_Fa_Status_Service { 5 | 6 | /** 7 | * Determine the two-factor status for a user. 8 | * 9 | * @return string 10 | */ 11 | public function determineStatus(int $userId, array $forcedRoles, int $daysThreshold): string { 12 | $totpStatus = get_user_meta($userId, 'rsssl_two_fa_status_totp', true); 13 | $emailStatus = get_user_meta($userId, 'rsssl_two_fa_status_email', true); 14 | $passkeyStatus = get_user_meta($userId, 'rsssl_two_fa_status_passkey', true); 15 | $lastLogin = get_user_meta($userId, 'rsssl_two_fa_last_login', true); 16 | 17 | if (in_array('active', [$totpStatus, $emailStatus, $passkeyStatus], true)) { 18 | return 'active'; 19 | } 20 | if ($totpStatus === 'disabled' && $emailStatus === 'disabled') { 21 | return 'disabled'; 22 | } 23 | foreach ($forcedRoles as $role) { 24 | if (in_array($role, get_userdata($userId)->roles, true) 25 | && strtotime($lastLogin) < strtotime("-$daysThreshold days") 26 | ) { 27 | return 'expired'; 28 | } 29 | } 30 | return $totpStatus ?: $emailStatus ?: 'open'; 31 | } 32 | } -------------------------------------------------------------------------------- /security/wordpress/user-registration.php: -------------------------------------------------------------------------------- 1 | <?php 2 | defined('ABSPATH') or die(); 3 | /** 4 | * Action to disable user registration 5 | * 6 | * @return bool 7 | */ 8 | function rsssl_users_can_register($value, $option) { 9 | return false; 10 | } 11 | add_filter( "option_users_can_register", 'rsssl_users_can_register', 999, 2 ); -------------------------------------------------------------------------------- /settings/build/index.a4cc556db77e3384994b.asset.php: -------------------------------------------------------------------------------- 1 | <?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => 'a4cc556db77e3384994b'); 2 | -------------------------------------------------------------------------------- /settings/config/fields/hibp-integration.php: -------------------------------------------------------------------------------- 1 | <?php 2 | defined( 'ABSPATH' ) or die(); 3 | 4 | add_filter( 'rsssl_fields', function ( $fields ) { 5 | return array_merge( $fields, 6 | [ 7 | [ 8 | 'id' => 'enable_hibp_check', 9 | 'menu_id' => 'password_security', 10 | 'group_id' => 'password_security_passwords', 11 | 'type' => 'checkbox', 12 | 'label' => __( 'Enable compromised password check', 'really-simple-ssl' ), 13 | 'tooltip' => __( "Prevent usage of passwords that have been included in a databreach. This securely verifies part of the hashed password via the Have I Been Pwned API.", 'really-simple-ssl' ), 14 | 'disabled' => false, 15 | 'default' => false, 16 | 'warning' => false, 17 | ], 18 | ] 19 | ); 20 | }, 200 ); -------------------------------------------------------------------------------- /settings/config/fields/letsencrypt.php: -------------------------------------------------------------------------------- 1 | <?php 2 | defined( 'ABSPATH' ) or die(); 3 | 4 | add_filter( 'rsssl_fields', function( $fields ) { 5 | return array_merge( $fields, 6 | [ 7 | [ 8 | 'id' => 'letsencrypt', 9 | 'menu_id' => 'encryption_lets_encrypt', 10 | 'group_id' => 'encryption_lets_encrypt', 11 | 'type' => 'lets-encrypt', 12 | 'default' => false, 13 | 'server_conditions' => [ 14 | 'relation' => 'AND', 15 | [ 16 | 'rsssl_letsencrypt_generation_allowed' => true, 17 | ] 18 | ], 19 | ], 20 | ] 21 | ); 22 | }, 200 ); 23 | -------------------------------------------------------------------------------- /settings/config/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /settings/config/mails.php: -------------------------------------------------------------------------------- 1 | <?php 2 | defined('ABSPATH') or die(); 3 | 4 | /** 5 | * @param $fields 6 | * 7 | * @return mixed 8 | */ 9 | function rsssl_mails(){ 10 | return apply_filters('rsssl_mails', [ 11 | 12 | ]); 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /settings/dist/bundle.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/settings/dist/bundle.js -------------------------------------------------------------------------------- /settings/dist/main.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:red;color:blue} 2 | -------------------------------------------------------------------------------- /settings/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /settings/src/Dashboard/GridBlock.js: -------------------------------------------------------------------------------- 1 | const GridBlock = (props) => { 2 | const footer =props.block.footer ? props.block.footer : false; 3 | const blockData = props.block; 4 | let className = "rsssl-grid-item "+blockData.class+" rsssl-"+blockData.id; 5 | return ( 6 | <div key={"block-"+blockData.id} className={className}> 7 | <div key={"header-"+blockData.id} className="rsssl-grid-item-header"> 8 | { blockData.header && wp.element.createElement(blockData.header) } 9 | { !blockData.header && <> 10 | <h3 className="rsssl-grid-title rsssl-h4">{ blockData.title }</h3> 11 | <div className="rsssl-grid-item-controls"></div> 12 | </> 13 | } 14 | </div> 15 | <div key={"content-"+blockData.id} className="rsssl-grid-item-content">{wp.element.createElement(props.block.content)}</div> 16 | { !footer && <div key={"footer-"+blockData.id} className="rsssl-grid-item-footer"></div>} 17 | { footer && <div key={"footer-"+blockData.id} className="rsssl-grid-item-footer">{wp.element.createElement(footer)}</div>} 18 | </div> 19 | ); 20 | } 21 | 22 | export default GridBlock; -------------------------------------------------------------------------------- /settings/src/Dashboard/OtherPlugins/OtherPluginsHeader.js: -------------------------------------------------------------------------------- 1 | import { __ } from '@wordpress/i18n'; 2 | const OtherPluginsHeader = () => { 3 | return ( 4 | <> 5 | <h3 className="rsssl-grid-title rsssl-h4">{ __( "Other Plugins", 'really-simple-ssl' ) }</h3> 6 | <div className="rsssl-grid-item-controls"> 7 | <span className="rsssl-header-html"> 8 | <a className="rsp-logo" href="https://really-simple-plugins.com/"><img src={rsssl_settings.plugin_url+"assets/img/really-simple-plugins.svg"} alt="Really Simple Plugins"/></a> 9 | </span> 10 | </div> 11 | </> 12 | ) 13 | } 14 | 15 | export default OtherPluginsHeader; -------------------------------------------------------------------------------- /settings/src/Dashboard/SslLabs/SslLabsFooter.js: -------------------------------------------------------------------------------- 1 | import { __ } from '@wordpress/i18n'; 2 | import useSslLabs from "./SslLabsData"; 3 | const SslLabsFooter = () => { 4 | const {sslScanStatus, setSslScanStatus, isLocalHost} = useSslLabs(); 5 | let disabled = sslScanStatus === 'active' || isLocalHost(); 6 | return ( 7 | <> 8 | <button disabled={disabled} onClick={ (e) => setSslScanStatus('active') } className="button button-default"> 9 | { sslScanStatus==='paused' && __("Continue SSL Health check", "really-simple-ssl")} 10 | { sslScanStatus!=='paused' && __("Check SSL Health", "really-simple-ssl")} 11 | </button> 12 | </> 13 | ) 14 | } 15 | 16 | export default SslLabsFooter; -------------------------------------------------------------------------------- /settings/src/Dashboard/SslLabs/SslLabsHeader.js: -------------------------------------------------------------------------------- 1 | import { __ } from '@wordpress/i18n'; 2 | const SslLabsHeader = () => { 3 | return ( 4 | <> 5 | <h3 className="rsssl-grid-title rsssl-h4">{ __( "Status", 'really-simple-ssl' ) }</h3> 6 | <div className="rsssl-grid-item-controls"> 7 | <span className="rsssl-header-html"> {__( "Powered by Qualys", 'really-simple-ssl' )}</span> 8 | </div> 9 | </> 10 | ) 11 | } 12 | 13 | export default SslLabsHeader; -------------------------------------------------------------------------------- /settings/src/Dashboard/TipsTricks/TipsTricksFooter.js: -------------------------------------------------------------------------------- 1 | import { __ } from '@wordpress/i18n'; 2 | import {addUrlRef} from "../../utils/AddUrlRef"; 3 | 4 | const TipsTricksFooter = () => { 5 | 6 | 7 | return ( 8 | <> 9 | <a href={addUrlRef("https://really-simple-ssl.com/knowledge-base-overview/")} target="_blank"rel="noopener noreferrer" className="button button-secondary">{ __("Documentation", "really-simple-ssl")}</a> 10 | </> 11 | 12 | ); 13 | 14 | } 15 | export default TipsTricksFooter -------------------------------------------------------------------------------- /settings/src/Dashboard/Vulnerabilities/VulnerabilitiesFooter.js: -------------------------------------------------------------------------------- 1 | import {useEffect, useState} from '@wordpress/element'; 2 | import {__} from '@wordpress/i18n'; 3 | import useRiskData from "../../Settings/RiskConfiguration/RiskData"; 4 | import useFields from "../../Settings/FieldsData"; 5 | import {getRelativeTime} from '../../utils/formatting'; 6 | 7 | const VulnerabilitiesFooter = (props) => { 8 | const {lastChecked} = useRiskData(); 9 | const {fields, getFieldValue} = useFields(); 10 | const [vulEnabled, setVulEnabled] = useState(false); 11 | useEffect(() => { 12 | if (getFieldValue('enable_vulnerability_scanner')==1) { 13 | setVulEnabled(true); 14 | } 15 | }, [fields]); 16 | 17 | const styleFooter = { 18 | textAlign: 'right', 19 | position: 'relative', 20 | right: '0', 21 | } 22 | return ( 23 | <> 24 | <a href="#settings/vulnerabilities" className={'button button-default'}>{__('Settings', 'really-simple-ssl')}</a> 25 | {vulEnabled? <p className={'rsssl-small-text'}>{getRelativeTime(lastChecked)}</p>: null} 26 | </> 27 | ) 28 | } 29 | 30 | export default VulnerabilitiesFooter; 31 | -------------------------------------------------------------------------------- /settings/src/Dashboard/Vulnerabilities/VulnerabilitiesHeader.js: -------------------------------------------------------------------------------- 1 | import { __ } from '@wordpress/i18n'; 2 | import {useEffect, useState} from "@wordpress/element"; 3 | import useFields from "../../Settings/FieldsData"; 4 | const VulnerabilitiesHeader = () => { 5 | const {fields, getFieldValue} = useFields(); 6 | const [vulEnabled, setVulEnabled] = useState(false); 7 | useEffect(() => { 8 | if (getFieldValue('enable_vulnerability_scanner')==1) { 9 | setVulEnabled(true); 10 | } 11 | }, [fields]); 12 | 13 | return ( 14 | <> 15 | <h3 className="rsssl-grid-title rsssl-h4">{ vulEnabled ? __( "Vulnerabilities", 'really-simple-ssl' ) : __( "Hardening", 'really-simple-ssl' ) }</h3> 16 | <div className="rsssl-grid-item-controls"> 17 | <span className="rsssl-header-html"></span> 18 | </div> 19 | </> 20 | ) 21 | } 22 | 23 | export default VulnerabilitiesHeader; -------------------------------------------------------------------------------- /settings/src/LetsEncrypt/Activate.js: -------------------------------------------------------------------------------- 1 | import Onboarding from "../Onboarding/Onboarding"; 2 | 3 | const Activate = () => { 4 | return ( 5 | <div className="rsssl-lets-encrypt-tests"> 6 | <Onboarding/> 7 | </div> 8 | ) 9 | } 10 | 11 | export default Activate; -------------------------------------------------------------------------------- /settings/src/Menu/Menu.js: -------------------------------------------------------------------------------- 1 | import MenuPlaceholder from '../Placeholder/MenuPlaceholder'; 2 | import MenuItem from './MenuItem'; 3 | import useMenu from "./MenuData"; 4 | /** 5 | * Menu block, rendering the entire menu 6 | */ 7 | const Menu = () => { 8 | const {subMenu, subMenuLoaded} = useMenu(); 9 | 10 | if ( !subMenuLoaded ) { 11 | return( 12 | <MenuPlaceholder /> 13 | ) 14 | } 15 | 16 | return ( 17 | <div className="rsssl-wizard-menu rsssl-grid-item"> 18 | <div className="rsssl-grid-item-header"> 19 | <h1 className="rsssl-h4">{subMenu.title}</h1> 20 | </div> 21 | <div className="rsssl-grid-item-content"> 22 | <div className="rsssl-wizard-menu-items"> 23 | { subMenu.menu_items.map((menuItem, i) => <MenuItem key={"menuItem-"+i} menuItem={menuItem} isMainMenu={true} /> ) } 24 | </div> 25 | </div> 26 | <div className="rsssl-grid-item-footer"> 27 | 28 | </div> 29 | </div> 30 | ) 31 | } 32 | export default Menu; 33 | -------------------------------------------------------------------------------- /settings/src/Modal/ModalControl.js: -------------------------------------------------------------------------------- 1 | import useModal from "./ModalData"; 2 | 3 | /** 4 | * Button to open the modal 5 | * @param props 6 | * @returns {JSX.Element} 7 | * @constructor 8 | */ 9 | const ModalControl = (props) => { 10 | const {handleModal} = useModal(); 11 | const onClickHandler = () => { 12 | handleModal(true, props.modalData, props.item ); 13 | } 14 | 15 | return ( 16 | <button className={"button button-" + props.btnStyle} onClick={ (e) => onClickHandler(e) }>{props.btnText}</button> 17 | ) 18 | } 19 | export default ModalControl -------------------------------------------------------------------------------- /settings/src/Modal/ModalData.js: -------------------------------------------------------------------------------- 1 | import {create} from 'zustand'; 2 | 3 | const useModalData = create(( set, get ) => ({ 4 | modalData: [], 5 | buttonsDisabled: false, 6 | showModal:false, 7 | ignoredItems:[], 8 | fixedItems:[], 9 | item:false, 10 | setIgnoredItemId: (ignoredItemId) => { 11 | let ignoredItems = get().ignoredItems; 12 | ignoredItems.push(ignoredItemId); 13 | set({ignoredItems: ignoredItems, }); 14 | }, 15 | setFixedItemId: (fixedItemId) => { 16 | let fixedItems = get().fixedItems; 17 | fixedItems.push(fixedItemId); 18 | set({fixedItems: fixedItems, }); 19 | }, 20 | handleModal: (showModal, modalData, item) => { 21 | set({showModal: showModal, modalData:modalData, item:item }); 22 | }, 23 | setModalData: (modalData) => { 24 | set({modalData:modalData }); 25 | }, 26 | })); 27 | 28 | export default useModalData; 29 | -------------------------------------------------------------------------------- /settings/src/Onboarding/Items/CheckboxItem.js: -------------------------------------------------------------------------------- 1 | import useOnboardingData from "../OnboardingData"; 2 | import {memo} from "@wordpress/element"; 3 | 4 | const CheckboxItem = ({item, disabled}) => { 5 | const { 6 | updateItemStatus, 7 | currentStep 8 | } = useOnboardingData(); 9 | let { title, description, id, activated } = item; 10 | return ( 11 | <li> 12 | <label className="rsssl-modal-checkbox-container"> 13 | <input type="checkbox" disabled={disabled} checked={activated} value={id} id={id} onChange={(e) => updateItemStatus(currentStep.id, id, null, null, e.target.checked )}/> 14 | <span className="rsssl-checkmark"></span> 15 | </label> 16 | {title} 17 | {description && <> - {description}</>} 18 | </li> 19 | ) 20 | } 21 | export default memo(CheckboxItem) -------------------------------------------------------------------------------- /settings/src/Onboarding/Items/PremiumItem.js: -------------------------------------------------------------------------------- 1 | import {memo} from "@wordpress/element"; 2 | const PremiumItem = ({item}) => { 3 | let { title } = item; 4 | return ( 5 | <li> 6 | <div className="rsssl-modal-premium-container"> 7 | PRO 8 | </div> 9 | {title} 10 | </li> 11 | ) 12 | } 13 | export default memo(PremiumItem) -------------------------------------------------------------------------------- /settings/src/Onboarding/PremiumItem.scss: -------------------------------------------------------------------------------- 1 | .rsssl-modal-premium-container { 2 | background-color: var(--rsp-dark-blue); 3 | color:#fff; 4 | padding:0 5px; 5 | margin-right:22px; 6 | } -------------------------------------------------------------------------------- /settings/src/Onboarding/Steps/StepConfig.js: -------------------------------------------------------------------------------- 1 | import { memo, useEffect } from "@wordpress/element"; 2 | import { __ } from "@wordpress/i18n"; 3 | import useOnboardingData from "../OnboardingData"; 4 | import useFields from "../../Settings/FieldsData"; 5 | import Host from "../../Settings/Host/Host"; 6 | import ListItem from "../Items/ListItem"; 7 | 8 | const StepConfig = ({ isModal }) => { 9 | const { fetchFieldsData, getField, fieldsLoaded, updateField, setChangedField, saveFields } = useFields(); 10 | const { currentStep } = useOnboardingData(); 11 | 12 | useEffect(() => { 13 | if (!fieldsLoaded) { 14 | fetchFieldsData(); 15 | } 16 | }, []); 17 | 18 | let otherHostsField = fieldsLoaded && getField('other_host_type'); 19 | let items = currentStep.items ? currentStep.items : []; 20 | 21 | if (rsssl_settings.cloudflare && !items.some(item => item.id === 'cf')) { 22 | let cfItem = { 23 | status: 'success', 24 | title: "CloudFlare", 25 | id: 'cf' 26 | }; 27 | items.unshift(cfItem); 28 | } 29 | 30 | return ( 31 | <> 32 | {isModal && <Host field={otherHostsField} showDisabledWhenSaving={false} />} 33 | <ul> 34 | {items && items.map((item, index) => <ListItem key={'step-config-' + index} item={item} />)} 35 | </ul> 36 | </> 37 | ); 38 | }; 39 | 40 | export default memo(StepConfig); 41 | -------------------------------------------------------------------------------- /settings/src/Onboarding/Steps/StepFeatures.js: -------------------------------------------------------------------------------- 1 | import {memo} from "@wordpress/element"; 2 | import useOnboardingData from "../OnboardingData"; 3 | import CheckboxItem from "../Items/CheckboxItem"; 4 | import PremiumItem from "../Items/PremiumItem"; 5 | 6 | const StepFeatures = () => { 7 | const { 8 | currentStep 9 | } = useOnboardingData(); 10 | 11 | let items = currentStep.items ? currentStep.items : []; 12 | let freeItems = items.filter( (item) => !item.premium ); 13 | let premiumItems = items.filter( (item) => item.premium ); 14 | return ( 15 | <> 16 | <ul> 17 | {freeItems && ( 18 | <div className="rsssl-checkbox-items"> 19 | {freeItems.map((item, index) => ( 20 | <CheckboxItem key={'step-features' + index} item={item}/> 21 | ))} 22 | </div> 23 | )} 24 | {premiumItems && ( 25 | <div className="rsssl-premium-items"> 26 | {premiumItems.map((item, index) => ( 27 | <PremiumItem key={'step-features' + index} item={item}/> 28 | ))} 29 | </div> 30 | )} 31 | </ul> 32 | </> 33 | ); 34 | } 35 | export default memo(StepFeatures) -------------------------------------------------------------------------------- /settings/src/Onboarding/Steps/StepLicense.js: -------------------------------------------------------------------------------- 1 | import {memo, useEffect, useRef} from "@wordpress/element"; 2 | import useOnboardingData from "../OnboardingData"; 3 | import License from "../../Settings/License/License"; 4 | import useFields from "../../Settings/FieldsData"; 5 | import useLicense from "../../Settings/License/LicenseData"; 6 | 7 | const StepLicense = () => { 8 | const { 9 | currentStepIndex, 10 | setCurrentStepIndex, 11 | } = useOnboardingData(); 12 | const { getField } = useFields(); 13 | const {licenseStatus} = useLicense(); 14 | const pro_plugin_active = rsssl_settings.pro_plugin_active; 15 | 16 | //skip step if either already active, or if not pro 17 | useEffect( () => { 18 | if ( ! pro_plugin_active || licenseStatus === 'valid' ) { 19 | setCurrentStepIndex(currentStepIndex + 1); 20 | } 21 | }, [licenseStatus, pro_plugin_active] ); 22 | 23 | return ( 24 | <div className={"rsssl-license"}> 25 | <License 26 | field={getField('license')} 27 | isOnboarding={true} 28 | /> 29 | </div> 30 | ); 31 | }; 32 | 33 | export default memo(StepLicense); -------------------------------------------------------------------------------- /settings/src/Onboarding/Steps/StepPlugins.js: -------------------------------------------------------------------------------- 1 | import {memo, useEffect} from "@wordpress/element"; 2 | import useOnboardingData from "../OnboardingData"; 3 | import CheckboxItem from "../Items/CheckboxItem"; 4 | 5 | const StepPlugins = () => { 6 | const { 7 | currentStep, 8 | currentStepIndex, 9 | setCurrentStepIndex, 10 | } = useOnboardingData(); 11 | 12 | useEffect(()=> { 13 | //if all plugins are already activated, we skip the plugins step 14 | let plugins = currentStep.items; 15 | if ( plugins.filter(item => item.action !== 'none').length === 0) { 16 | setCurrentStepIndex(currentStepIndex+1); 17 | } 18 | }, [] ); 19 | 20 | let plugins = currentStep.items; 21 | 22 | return ( 23 | <> 24 | <ul> 25 | { plugins && plugins.map( (item, index) => <CheckboxItem key={'step-plugins'+index} item={item} disabled={item.action==='none'} />) } 26 | </ul> 27 | </> 28 | ); 29 | } 30 | export default memo(StepPlugins); -------------------------------------------------------------------------------- /settings/src/Onboarding/Steps/StepPro.js: -------------------------------------------------------------------------------- 1 | import {memo} from "@wordpress/element"; 2 | import useOnboardingData from "../OnboardingData"; 3 | import CheckboxItem from "../Items/CheckboxItem"; 4 | import PremiumItem from "../Items/PremiumItem"; 5 | 6 | const StepPro = () => { 7 | const { 8 | currentStep, 9 | } = useOnboardingData(); 10 | 11 | let premiumItems = currentStep.items; 12 | return ( 13 | <> 14 | <ul> 15 | {!rsssl_settings.pro_plugin_active && premiumItems && ( 16 | <div className="rsssl-premium-items"> 17 | {premiumItems.map((item, index) => ( 18 | <PremiumItem key={'step-pro' + index} item={item}/> 19 | ))} 20 | </div> 21 | )} 22 | {rsssl_settings.pro_plugin_active && premiumItems && ( 23 | <div className="rsssl-checkbox-items"> 24 | {premiumItems.map((item, index) => ( 25 | <CheckboxItem key={'step-pro' + index} item={item}/> 26 | ))} 27 | </div> 28 | )} 29 | </ul> 30 | </> 31 | ); 32 | } 33 | export default memo(StepPro); -------------------------------------------------------------------------------- /settings/src/Onboarding/onboarding.scss: -------------------------------------------------------------------------------- 1 | .rsssl-modal.rsssl-onboarding-modal .rsssl-modal-body, .rsssl-letsencrypt .rsssl-le-activate_ssl { 2 | 3 | .rsssl-override-detection-toggle { 4 | margin-bottom: -15px; 5 | } 6 | input[type=email] { 7 | width: 100%; 8 | margin-bottom: var(--rsp-spacing-m); 9 | border: 2px solid; 10 | height: 50px; 11 | border-color: var(--rsp-grey-300); 12 | } 13 | //hide select label 14 | .rsssl-select { 15 | label { 16 | display: none; 17 | } 18 | .components-select-control__input{ 19 | height:45px; 20 | padding: 8px 20px; 21 | color: var(--rsp-grey-500); 22 | } 23 | } 24 | 25 | .rsssl-activate_ssl, .rsssl-plugins { 26 | ul { 27 | column-count: 1; 28 | } 29 | } 30 | 31 | ul { 32 | li { 33 | display: flex; 34 | align-items: flex-start; 35 | margin-bottom: var(--rsp-spacing-xxs); 36 | &.rsssl-is-plugin{ 37 | background-color: var(--rsp-grey-100); 38 | border: none; 39 | margin: 10px 0; 40 | padding:5px 0; 41 | position:relative; 42 | } 43 | .rsssl-icon{ 44 | margin-right:7px; 45 | } 46 | } 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /settings/src/Placeholder/DashboardPlaceholder.js: -------------------------------------------------------------------------------- 1 | const DashboardPlaceholder = (props) => { 2 | return ( 3 | <> 4 | <div className="rsssl-grid-item rsssl-column-2 rsssl-dashboard-placeholder"></div> 5 | <div className="rsssl-grid-item rsssl-row-2 rsssl-dashboard-placeholder"></div> 6 | <div className="rsssl-grid-item rsssl-row-2 rsssl-dashboard-placeholder"></div> 7 | </> 8 | ); 9 | } 10 | 11 | export default DashboardPlaceholder; 12 | 13 | -------------------------------------------------------------------------------- /settings/src/Placeholder/DatatablePlaceholder.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | const DatatablePlaceholder = (props) => { 3 | let lines = props.lines; 4 | if ( !lines ) lines = 3; 5 | return ( 6 | <div className="rsssl-datatable-placeholder"> 7 | {Array.from({length: lines}).map((item, i) => (<div key={'datatable-placeholder-'+i} ></div>))} 8 | </div> 9 | ); 10 | 11 | } 12 | 13 | export default DatatablePlaceholder; -------------------------------------------------------------------------------- /settings/src/Placeholder/MenuPlaceholder.js: -------------------------------------------------------------------------------- 1 | const MenuPlaceholder = () => { 2 | return ( 3 | <div className="rsssl-wizard-menu rsssl-grid-item rsssl-menu-placeholder"> 4 | <div className="rsssl-grid-item-header"> 5 | <h1 className="rsssl-h4"></h1> 6 | </div> 7 | <div className="rsssl-grid-item-content"></div> 8 | </div> 9 | ); 10 | } 11 | 12 | export default MenuPlaceholder; -------------------------------------------------------------------------------- /settings/src/Placeholder/PagePlaceholder.js: -------------------------------------------------------------------------------- 1 | import Error from '../utils/Error'; 2 | const PagePlaceholder = (props) => { 3 | return ( 4 | <> 5 | <div className="rsssl-header-container"> 6 | <div className="rsssl-header"> 7 | <img className="rsssl-logo" 8 | src={rsssl_settings.plugin_url + 'assets/img/really-simple-security-logo.svg'} 9 | alt="Really Simple Security logo"/> 10 | </div> 11 | </div> 12 | <div className="rsssl-content-area rsssl-grid rsssl-dashboard rsssl-page-placeholder"> 13 | <div className="rsssl-grid-item rsssl-column-2 rsssl-row-2 "> 14 | {props.error && <Error error={props.error} /> } 15 | </div> 16 | <div className="rsssl-grid-item rsssl-row-2"></div> 17 | <div className="rsssl-grid-item rsssl-row-2"></div> 18 | <div className="rsssl-grid-item rsssl-column-2"></div> 19 | </div> 20 | </> 21 | ); 22 | } 23 | 24 | export default PagePlaceholder; 25 | 26 | -------------------------------------------------------------------------------- /settings/src/Placeholder/Placeholder.js: -------------------------------------------------------------------------------- 1 | import Error from "../utils/Error"; 2 | 3 | const Placeholder = (props) => { 4 | 5 | let lines = props.lines; 6 | if ( !lines ) lines = 4; 7 | if (props.error) { 8 | lines = 0; 9 | } 10 | return ( 11 | <div className="rsssl-placeholder"> 12 | {props.error && <Error error={props.error} /> } 13 | {Array.from({length: lines}).map((item, i) => (<div className="rsssl-placeholder-line" key={"placeholder-"+i} ></div>))} 14 | </div> 15 | ); 16 | 17 | } 18 | 19 | export default Placeholder; -------------------------------------------------------------------------------- /settings/src/Placeholder/SettingsPlaceholder.js: -------------------------------------------------------------------------------- 1 | import Placeholder from "./Placeholder"; 2 | 3 | /** 4 | * Menu block, rendering the entire menu 5 | */ 6 | const SettingsPlaceholder = () => { 7 | return( 8 | <div className="rsssl-wizard-settings rsssl-column-2 rsssl-settings-placeholder"> 9 | <div className="rsssl-grid-item"> 10 | <div className="rsssl-grid-item-content"> 11 | <div className="rsssl-settings-block-intro"></div> 12 | </div> 13 | </div> 14 | <div className="rsssl-grid-item-footer"></div> 15 | </div> 16 | ) 17 | } 18 | 19 | export default SettingsPlaceholder; 20 | -------------------------------------------------------------------------------- /settings/src/Settings/AutoComplete/AutoComplete.scss: -------------------------------------------------------------------------------- 1 | .rsssl-modal-body, .rsssl { 2 | input.MuiInput-underline:before { 3 | display:none; 4 | } 5 | .MuiAutocomplete-root { 6 | .MuiInputLabel-outlined[data-shrink=false] { 7 | transform: translate(14px, 16px) scale(1); 8 | } 9 | .MuiFormLabel-root { 10 | font-family:inherit; 11 | } 12 | .MuiOutlinedInput-root { 13 | padding: 0; 14 | } 15 | } 16 | input.MuiAutocomplete-input[type=text] { 17 | &:focus { 18 | outline: none; 19 | box-shadow:none; 20 | } 21 | border:0; 22 | padding-left:12px; 23 | } 24 | .MuiInputBase-root { 25 | font-family: inherit; 26 | } 27 | 28 | .MuiInput-root input.MuiInputBase-input { 29 | padding-left:10px; 30 | } 31 | .MuiPopper-root, .MuiPaper-root { 32 | max-height:150px; 33 | z-index: 999999; 34 | div { 35 | font-family: inherit !important; 36 | } 37 | ul { 38 | max-height:initial; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /settings/src/Settings/Captcha/CaptchaKey.js: -------------------------------------------------------------------------------- 1 | import Icon from "../../utils/Icon"; 2 | import useFields from "../FieldsData"; 3 | import {TextControl} from "@wordpress/components"; // assuming you're using WordPress components 4 | 5 | const CaptchaKey = ({ field, fields, label }) => { 6 | const { getFieldValue, setChangedField, updateField, saveFields} = useFields(); 7 | 8 | let fieldValue = getFieldValue(field.id); 9 | let captchaVerified = getFieldValue('captcha_fully_enabled'); 10 | 11 | const onChangeHandler = async (fieldValue) => { 12 | setChangedField(field.id, fieldValue); 13 | setChangedField('captcha_fully_enabled', false); 14 | updateField(field.id, fieldValue); 15 | await saveFields(false, false); 16 | } 17 | 18 | return ( 19 | <> 20 | <TextControl 21 | required={field.required} 22 | placeholder={field.placeholder} 23 | help={field.comment} 24 | label={label} 25 | onChange={(value) => onChangeHandler(value)} 26 | value={fieldValue} 27 | /> 28 | 29 | <div className="rsssl-email-verified" > 30 | {Boolean(captchaVerified) 31 | ? <Icon name='circle-check' color={'green'} /> 32 | : <Icon name='circle-times' color={'red'} /> 33 | } 34 | </div> 35 | </> 36 | ); 37 | } 38 | 39 | export default CaptchaKey; -------------------------------------------------------------------------------- /settings/src/Settings/Captcha/HCaptcha.js: -------------------------------------------------------------------------------- 1 | import {useEffect} from "@wordpress/element"; 2 | const HCaptcha = ({ sitekey, handleCaptchaResponse }) => { 3 | const hcaptchaCallback = (response) => { 4 | handleCaptchaResponse(response); 5 | }; 6 | 7 | useEffect(() => { 8 | const script = document.createElement('script'); 9 | 10 | script.src = `https://hcaptcha.com/1/api.js?onload=initHcaptcha`; 11 | script.async = true; 12 | script.defer = true; 13 | 14 | script.onload = () => { 15 | if (typeof window.hcaptcha !== 'undefined') { 16 | window.hcaptcha.render('hcaptchaContainer', { 17 | sitekey: sitekey, 18 | callback: hcaptchaCallback 19 | }); 20 | } 21 | }; 22 | 23 | document.body.appendChild(script); 24 | 25 | // Cleanup function 26 | return () => { 27 | // Check if hcaptcha is loaded before trying to remove it 28 | if (window.hcaptcha) { 29 | window.hcaptcha.reset(); 30 | } 31 | if (script) { 32 | script.remove(); 33 | } 34 | }; 35 | 36 | }, [sitekey, handleCaptchaResponse]); 37 | 38 | return ( 39 | <div className="rsssl-captcha" 40 | style={{display: 'flex', flexDirection: 'column', alignItems: 'center', marginBottom: '20px'}}> 41 | <div id='hcaptchaContainer'></div> 42 | </div> 43 | ); 44 | }; 45 | 46 | export default HCaptcha; -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/Buttons/Buttons.scss: -------------------------------------------------------------------------------- 1 | .rsssl-datatable-component { 2 | 3 | .rsssl-action-buttons__inner { 4 | .rsssl-action-buttons__button { 5 | &.rsssl-red { 6 | border: 0 solid transparent; 7 | background: var(--rsp-red); 8 | color: var(--rsp-text-color-white); 9 | 10 | &:hover { 11 | background: var(--rsp-dark-red); 12 | color: var(--rsp-text-color-white); 13 | 14 | } 15 | } 16 | } 17 | } 18 | 19 | .rsssl-add-button__button, .rsssl-action-buttons__button { 20 | //display: flex; 21 | 22 | .rsssl-icon { 23 | margin-right: 10px; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/Buttons/ControlButton.js: -------------------------------------------------------------------------------- 1 | import DataTableStore from "../DataTableStore"; 2 | import './Buttons.scss' 3 | import Icon from "../../../utils/Icon"; 4 | const ControlButton = ({ controlButton }) => { 5 | const { 6 | processing, 7 | } = DataTableStore(); 8 | return ( 9 | <div className="rsssl-add-button"> 10 | <div className="rsssl-add-button__inner"> 11 | <button 12 | className="button button-secondary button-datatable rsssl-add-button__button" 13 | onClick={controlButton.onClick} 14 | disabled={processing} 15 | > 16 | {processing && <Icon name = "loading" color = 'grey' />} 17 | {controlButton.label} 18 | </button> 19 | </div> 20 | </div> 21 | ); 22 | }; 23 | export default ControlButton; -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/Buttons/MultiSelectButton.js: -------------------------------------------------------------------------------- 1 | import DataTableStore from "../DataTableStore"; 2 | import './Buttons.scss' 3 | import Icon from "../../../utils/Icon"; 4 | import {memo} from "@wordpress/element"; 5 | 6 | const MultiSelectButton = ({ids, buttonData}) => { 7 | const { 8 | processing, 9 | rowAction, 10 | } = DataTableStore(); 11 | return ( 12 | <div className={`rsssl-action-buttons__inner`}> 13 | <button 14 | className={`button ${buttonData.className} rsssl-action-buttons__button`} 15 | onClick={(e) => rowAction(ids, buttonData.action, buttonData.type, buttonData.reloadFields) } 16 | disabled={processing} 17 | > 18 | {processing && <Icon name = "loading" color = 'grey' />} 19 | {buttonData.label} 20 | </button> 21 | </div> 22 | ); 23 | }; 24 | export default memo(MultiSelectButton) -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/Buttons/RowButton.js: -------------------------------------------------------------------------------- 1 | import DataTableStore from "../DataTableStore"; 2 | import './Buttons.scss' 3 | import Icon from "../../../utils/Icon"; 4 | import {memo} from "@wordpress/element"; 5 | 6 | const RowButton = ({id, buttonData}) => { 7 | const { 8 | processing, 9 | rowAction, 10 | } = DataTableStore(); 11 | return ( 12 | <div className={`rsssl-action-buttons__inner`}> 13 | <button 14 | className={`button ${buttonData.className} rsssl-action-buttons__button`} 15 | onClick={(e) => rowAction([id], buttonData.action, buttonData.type, buttonData.reloadFields) } 16 | disabled={processing} 17 | > 18 | {buttonData.label} 19 | </button> 20 | </div> 21 | ); 22 | }; 23 | export default memo(RowButton); -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/Checkboxes.scss: -------------------------------------------------------------------------------- 1 | //style for checkbox when some rows are selected 2 | .rsssl-indeterminate { 3 | input[name="select-all-rows"] { 4 | background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect x="10" y="45" width="80" height="10" fill="currentColor"/></svg>') no-repeat center center; 5 | } 6 | } 7 | 8 | //style for checkbox when all rows are selected 9 | .rsssl-all-selected { 10 | input[name="select-all-rows"]::before { 11 | content: url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%233582c4%27%2F%3E%3C%2Fsvg%3E); 12 | margin: -0.1875rem 0 0 -0.25rem; 13 | height: 1.3125rem; 14 | width: 1.3125rem; 15 | } 16 | } -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/DataTable.scss: -------------------------------------------------------------------------------- 1 | .rsssl-datatable-component { 2 | margin-left: calc(0px - var(--rsp-spacing-l)); 3 | margin-right: calc(0px - var(--rsp-spacing-l)); 4 | >div { 5 | //prevent scrollbar on datatable 6 | overflow: hidden; 7 | } 8 | 9 | 10 | 11 | .rdt_TableCol, .rdt_TableCell, .rdt_TableCol_Sortable { 12 | flex-direction: row; 13 | } 14 | 15 | .rdt_TableCol:first-child, .rdt_TableCell:first-child { 16 | min-width: initial; 17 | } 18 | 19 | .rdt_TableHeadRow { 20 | .rdt_TableCol:last-child { 21 | flex-grow: 0; 22 | flex-direction: row-reverse; 23 | min-width: initial; 24 | } 25 | } 26 | 27 | .rdt_TableRow { 28 | &:nth-child(odd) { 29 | background-color: var(--rsp-grey-200) 30 | } 31 | 32 | padding: var(--rsp-spacing-xs) 0; 33 | .rdt_TableCell:last-child { 34 | flex-grow: 0; 35 | } 36 | } 37 | 38 | 39 | 40 | //wp-core also adds an svg for the select dropdown, so we hide the one from the react datatables component 41 | nav.rdt_Pagination > div > svg { 42 | display: none !important; 43 | } 44 | 45 | 46 | 47 | .rsssl-container { 48 | padding: 2em; 49 | display: flex; 50 | align-items: center; 51 | justify-content: space-between; 52 | } 53 | 54 | } 55 | 56 | -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/SearchBar/SearchBar.js: -------------------------------------------------------------------------------- 1 | import { useState } from '@wordpress/element'; 2 | import { __ } from '@wordpress/i18n'; 3 | import './SearchBar.scss'; 4 | import {memo} from "@wordpress/element"; 5 | 6 | const SearchBar = ({ handleSearch, searchableColumns }) => { 7 | const [debounceTimer, setDebounceTimer] = useState(null); 8 | 9 | const onKeyUp = (event) => { 10 | clearTimeout(debounceTimer); 11 | setDebounceTimer(setTimeout(() => { 12 | handleSearch(event.target.value, searchableColumns) 13 | }, 500)); 14 | }; 15 | 16 | return ( 17 | <div className="rsssl-search-bar"> 18 | <div className="rsssl-search-bar__inner"> 19 | <div className="rsssl-search-bar__icon"></div> 20 | <input 21 | type="text" 22 | className="rsssl-search-bar__input" 23 | placeholder={__("Search", "really-simple-ssl")} 24 | onKeyUp={onKeyUp} 25 | /> 26 | </div> 27 | </div> 28 | ) 29 | } 30 | 31 | export default memo(SearchBar); -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/SearchBar/SearchBar.scss: -------------------------------------------------------------------------------- 1 | .rsssl-search-bar { 2 | float: right; 3 | padding: 0; 4 | } 5 | 6 | .rsssl-search-bar__inner { 7 | display: flex; 8 | align-items: center; 9 | border-radius: 3px; 10 | transition: background-color 0.3s ease; 11 | } 12 | 13 | .rsssl-search-bar__inner:focus-within { 14 | background-color: #fff; 15 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 16 | } 17 | 18 | .rsssl-search-bar__icon { 19 | /* Add styles for the search icon */ 20 | } 21 | 22 | .rsssl-search-bar__input { 23 | border: none; 24 | outline: none; 25 | padding: 3px 5px; 26 | width: 150px; /* Adjust width as needed */ 27 | transition: width 0.3s ease; 28 | } 29 | 30 | .rsssl-search-bar__input:focus { 31 | width: 200px; /* Adjust width as needed */ 32 | } -------------------------------------------------------------------------------- /settings/src/Settings/DataTable/SelectedRowsControl/SelectedRowsControl.scss: -------------------------------------------------------------------------------- 1 | .rsssl-selected-rows-control { 2 | margin-top: 1em; 3 | margin-bottom: 1em; 4 | 5 | //blue container above datatable for multiselect 6 | .rsssl-multiselect-datatable-form { 7 | display: flex; 8 | align-items: center; 9 | Justify-content: space-between; 10 | width: 100%; 11 | padding: 1em 2em; 12 | background: var(--rsp-blue-faded); 13 | } 14 | } -------------------------------------------------------------------------------- /settings/src/Settings/DynamicDataTable/AddButton.js: -------------------------------------------------------------------------------- 1 | const AddButton = ({ getCurrentFilter, moduleName, handleOpen, processing, blockedText, allowedText }) => { 2 | let buttonText = getCurrentFilter(moduleName) === 'blocked' ? blockedText : allowedText; 3 | 4 | return ( 5 | <div className="rsssl-add-button"> 6 | {(getCurrentFilter(moduleName) === 'blocked' || getCurrentFilter(moduleName) === 'allowed') && ( 7 | <div className="rsssl-add-button__inner"> 8 | <button 9 | className="button button-secondary button-datatable rsssl-add-button__button" 10 | onClick={handleOpen} 11 | disabled={processing} 12 | > 13 | {buttonText} 14 | </button> 15 | </div> 16 | )} 17 | </div> 18 | ); 19 | }; 20 | 21 | export default AddButton; -------------------------------------------------------------------------------- /settings/src/Settings/DynamicDataTable/SearchBar.js: -------------------------------------------------------------------------------- 1 | import { useState } from '@wordpress/element'; 2 | import { __ } from '@wordpress/i18n'; 3 | 4 | const SearchBar = ({ handleSearch, searchableColumns }) => { 5 | const [debounceTimer, setDebounceTimer] = useState(null); 6 | 7 | const onKeyUp = (event) => { 8 | clearTimeout(debounceTimer); 9 | setDebounceTimer(setTimeout(() => { 10 | handleSearch(event.target.value, searchableColumns) 11 | }, 500)); 12 | }; 13 | 14 | return ( 15 | <div className="rsssl-search-bar"> 16 | <div className="rsssl-search-bar__inner"> 17 | <div className="rsssl-search-bar__icon"></div> 18 | <input 19 | type="text" 20 | className="rsssl-search-bar__input" 21 | placeholder={__("Search", "really-simple-ssl")} 22 | onKeyUp={onKeyUp} 23 | /> 24 | </div> 25 | </div> 26 | ) 27 | } 28 | 29 | export default SearchBar; -------------------------------------------------------------------------------- /settings/src/Settings/FilterData.js: -------------------------------------------------------------------------------- 1 | // FilterData.js 2 | import {create} from 'zustand'; 3 | 4 | const filterData = create((set, get) => ({ 5 | selectedFilter: [], 6 | processingFilter: false, 7 | setSelectedFilter: (selectedFilter, activeGroupId) => { 8 | set((state) => ({ 9 | //we make it an array, so we can have multiple filters 10 | selectedFilter: {...state.selectedFilter, [activeGroupId]: selectedFilter}, 11 | })); 12 | }, 13 | getCurrentFilter: (activeGroupId) => get().selectedFilter[activeGroupId], 14 | setProcessingFilter: (processingFilter) => set({processingFilter}), 15 | })); 16 | 17 | export default filterData; 18 | -------------------------------------------------------------------------------- /settings/src/Settings/GeoBlockList/AddButton.js: -------------------------------------------------------------------------------- 1 | import Icon from "../../utils/Icon"; 2 | 3 | const AddButton = ({ getCurrentFilter, moduleName, handleOpen, processing, blockedText, allowedText, disabled }) => { 4 | return ( 5 | <div className="rsssl-add-button"> 6 | <div className="rsssl-add-button__inner"> 7 | <button 8 | className="button button-secondary button-datatable rsssl-add-button__button" 9 | onClick={handleOpen} 10 | disabled={disabled} 11 | > 12 | {allowedText}{processing && <Icon name = "loading" color = 'grey' />} 13 | </button> 14 | </div> 15 | </div> 16 | ); 17 | }; 18 | 19 | export default AddButton; -------------------------------------------------------------------------------- /settings/src/Settings/GroupFilter.js: -------------------------------------------------------------------------------- 1 | // GroupFilter.js 2 | import { useState, useRef, useEffect } from "@wordpress/element"; 3 | import { __ } from "@wordpress/i18n"; 4 | 5 | const GroupFilter = ({ groupFilter, filterId, selectedFilter, setSelectedFilter }) => { 6 | if (!groupFilter) { 7 | return null; 8 | } 9 | return ( 10 | <div className="rsssl-grid-item-controls"> 11 | <select 12 | className="rsssl-group-filter" 13 | id={filterId} 14 | name={filterId} 15 | value={selectedFilter[filterId]} 16 | onChange={(e) => { 17 | const selectedValue = e.target.value; 18 | setSelectedFilter(selectedValue, filterId); 19 | }} 20 | > 21 | {groupFilter.options.map((option) => ( 22 | <option key={`option-${option.id}`} value={option.id}> 23 | {option.title} 24 | </option> 25 | ))} 26 | </select> 27 | </div> 28 | ); 29 | }; 30 | 31 | export default GroupFilter; -------------------------------------------------------------------------------- /settings/src/Settings/Host/HostData.js: -------------------------------------------------------------------------------- 1 | import {create} from 'zustand'; 2 | import * as rsssl_api from "../../utils/api"; 3 | const useHostData = create(( set, get ) => ({ 4 | hosts: [], 5 | hostsLoaded:false, 6 | fetchHosts: async ( id ) => { 7 | try { 8 | const response = await rsssl_api.doAction('get_hosts', { id: id }); 9 | 10 | // Handle the response 11 | if ( !response ) { 12 | console.error('No response received from the server.'); 13 | return; 14 | } 15 | let hosts = response.hosts; 16 | // Set the roles state with formatted data 17 | set({hosts: hosts,hostsLoaded:true }); 18 | } catch (error) { 19 | console.error('Error:', error); 20 | } 21 | } 22 | })); 23 | 24 | export default useHostData; 25 | 26 | -------------------------------------------------------------------------------- /settings/src/Settings/LearningMode/ChangeStatus.js: -------------------------------------------------------------------------------- 1 | import { __ } from '@wordpress/i18n'; 2 | import useLearningMode from "./LearningModeData"; 3 | const ChangeStatus = (props) => { 4 | const {updateStatus} = useLearningMode(); 5 | 6 | let statusClass = props.item.status==1 ? 'button button-primary rsssl-status-allowed' : 'button button-default rsssl-status-revoked'; 7 | let label = props.item.status==1 ? __("Revoke", "really-simple-ssl") : __("Allow", "really-simple-ssl"); 8 | return ( 9 | <button onClick={ () => updateStatus( props.item.status, props.item, props.field.id ) } className={statusClass}>{label}</button> 10 | ) 11 | } 12 | export default ChangeStatus -------------------------------------------------------------------------------- /settings/src/Settings/LearningMode/Delete.js: -------------------------------------------------------------------------------- 1 | import useLearningMode from "./LearningModeData"; 2 | import {__} from "@wordpress/i18n"; 3 | 4 | const Delete = (props) => { 5 | const {deleteData} = useLearningMode(); 6 | 7 | return ( 8 | <button type="button" className="button button-red rsssl-learning-mode-delete" onClick={ () => deleteData( props.item, props.field.id ) }> 9 | {/*<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" height="16" >*/} 10 | {/* <path fill="#000000" d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/>*/} 11 | {/*</svg>*/} 12 | {__("Delete", "really-simple-ssl")} 13 | </button> 14 | ) 15 | } 16 | export default Delete -------------------------------------------------------------------------------- /settings/src/Settings/LearningMode/ManualCspAddition.js: -------------------------------------------------------------------------------- 1 | import { create } from 'zustand'; 2 | import * as rsssl_api from "../../utils/api"; 3 | 4 | const ManualCspAddition = create((set, get) => ({ 5 | manualAdditionProcessing: false, 6 | manualAdditionData: [], 7 | manualAdditionDataLoaded: false, 8 | cspUri: '', 9 | directive: '', 10 | 11 | setDirective: (directive) => set({ directive }), 12 | setCspUri: (cspUri) => set({ cspUri }), 13 | setDataLoaded: (manualAdditionDataLoaded) => set({ manualAdditionDataLoaded }), 14 | addManualCspEntry: async (cspUri, directive) => { 15 | let response; 16 | 17 | set({ manualAdditionProcessing: true }); 18 | 19 | try { 20 | response = await rsssl_api.doAction('rsssl_csp_uri_add', { cspUri, directive }); 21 | if (response.request_success) { 22 | set({ manualAdditionDataLoaded: false }); 23 | } 24 | } catch (e) { 25 | console.error(e); 26 | } finally { 27 | set({ manualAdditionProcessing: false, manualAdditionDataLoaded: true }); 28 | } 29 | 30 | // Should contain keys "success" and "message"; 31 | return response; 32 | } 33 | })); 34 | 35 | export default ManualCspAddition; -------------------------------------------------------------------------------- /settings/src/Settings/LimitLoginAttempts/IpAddressInput.js: -------------------------------------------------------------------------------- 1 | import {useState} from '@wordpress/element'; 2 | import {__} from "@wordpress/i18n"; 3 | import Icon from "../../utils/Icon"; 4 | import IpAddressDataTableStore from "./IpAddressDataTableStore"; 5 | 6 | 7 | /** 8 | * Visual aid for adding an IP address to the list of blocked IP addresses 9 | * 10 | * @param props 11 | * @returns {*} 12 | * @constructor 13 | */ 14 | const IpAddressInput = (props) => { 15 | 16 | const [value, setValue] = useState(""); 17 | const [error, setError] = useState(false); 18 | const {maskError, setMaskError} = IpAddressDataTableStore(); 19 | 20 | return ( 21 | <> 22 | {props.label && 23 | <label 24 | htmlFor={props.id} 25 | className="rsssl-label" 26 | >{props.label}</label> 27 | } 28 | <br></br> 29 | <div className="input-container"> 30 | <input 31 | type="text" 32 | id={props.id} 33 | name={props.name} 34 | value={props.value} 35 | className={`rsssl-input full ${maskError ? 'rsssl-error' : 'rsssl-success'}`} 36 | onChange={props.onChange} 37 | /> 38 | </div> 39 | {maskError && <span 40 | style={{color: 'red', marginLeft: '10px'}}>{__('Invalid ip address', 'really-simple-ssl')}</span>} 41 | </> 42 | ) 43 | } 44 | 45 | export default IpAddressInput; -------------------------------------------------------------------------------- /settings/src/Settings/LimitLoginAttempts/LimitLoginAttemptsData.js: -------------------------------------------------------------------------------- 1 | /* Creates A Store For Risk Data using Zustand */ 2 | import {create} from 'zustand'; 3 | import * as rsssl_api from "../../utils/api"; 4 | import {__} from "@wordpress/i18n"; 5 | import {produce} from "immer"; 6 | import React from "react"; 7 | 8 | const LimitLoginAttemptsData = create((set, get) => ({ 9 | 10 | processing:false, 11 | dataLoaded: false, 12 | EventLog: [], 13 | 14 | fetchEventLog: async (selectedFilter) => { 15 | set({processing:true}); 16 | try { 17 | let response = await rsssl_api.doAction(selectedFilter); 18 | set({EventLog: response, dataLoaded: true, processing:false}); 19 | } catch (e) { 20 | console.log(e); 21 | } 22 | } 23 | })); 24 | 25 | export default LimitLoginAttemptsData; -------------------------------------------------------------------------------- /settings/src/Settings/Notices.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Notice after saving was successfull 3 | */ 4 | import { SnackbarList } from '@wordpress/components'; 5 | import { 6 | useDispatch, 7 | useSelect, 8 | } from '@wordpress/data'; 9 | 10 | import { store as noticesStore } from '@wordpress/notices'; 11 | 12 | const Notices = () => { 13 | const notices = useSelect( 14 | ( select ) => 15 | select( noticesStore ) 16 | .getNotices() 17 | .filter( ( notice ) => notice.type === 'snackbar' ), 18 | [] 19 | ); 20 | if ( typeof notices === 'undefined' ) { 21 | return (<></>) 22 | } 23 | const { removeNotice } = useDispatch( noticesStore ); 24 | return ( 25 | <SnackbarList 26 | className="edit-site-notices" 27 | notices={ notices } 28 | onRemove={ removeNotice } 29 | /> 30 | ); 31 | }; 32 | 33 | export default Notices; -------------------------------------------------------------------------------- /settings/src/Settings/Password.js: -------------------------------------------------------------------------------- 1 | import useFields from "./FieldsData"; 2 | 3 | const Password = (props) => { 4 | const {updateField, setChangedField} = useFields(); 5 | 6 | const onChangeHandler = (fieldValue) => { 7 | updateField( props.field.id, fieldValue ); 8 | setChangedField( props.field.id, fieldValue ); 9 | } 10 | 11 | /** 12 | * There is no "PasswordControl" in WordPress react yet, so we create our own license field. 13 | */ 14 | return ( 15 | <div className="components-base-control"> 16 | <div className="components-base-control__field"> 17 | <label 18 | className="components-base-control__label" 19 | htmlFor={props.field.id}>{props.field.label}</label> 20 | <input className="components-text-control__input" 21 | type="password" 22 | id={props.field.id} 23 | value={props.field.value} 24 | onChange={ ( e ) => onChangeHandler(e.target.value) } 25 | /> 26 | </div> 27 | </div> 28 | ); 29 | } 30 | 31 | export default Password; -------------------------------------------------------------------------------- /settings/src/Settings/RiskConfiguration/datatable.scss: -------------------------------------------------------------------------------- 1 | .rsssl-vulnerabilities_overview { 2 | div[data-column-id="4"].rdt_TableCol { 3 | display:block; 4 | } 5 | 6 | .rdt_TableCell:last-child { 7 | flex: auto; 8 | padding-right: 20px; 9 | margin-right: 0; 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /settings/src/Settings/RiskConfiguration/modal.scss: -------------------------------------------------------------------------------- 1 | .rsssl-modal.rsssl-vulnerabilities-modal{ 2 | ul { 3 | column-count: 1; 4 | } 5 | } -------------------------------------------------------------------------------- /settings/src/Settings/TwoFA/RolesStore.js: -------------------------------------------------------------------------------- 1 | import {create} from 'zustand'; 2 | import * as rsssl_api from "../../utils/api"; 3 | import {produce} from "immer"; 4 | const useRolesData = create(( set, get ) => ({ 5 | roles: [], 6 | rolesLoaded:false, 7 | fetchRoles: async ( id ) => { 8 | try { 9 | // Fetch the roles from the server using rsssl_api.getUserRoles() 10 | const response = await rsssl_api.doAction('get_roles', { id: id }); 11 | 12 | // Handle the response 13 | if ( !response ) { 14 | console.error('No response received from the server.'); 15 | return; 16 | } 17 | 18 | const data = response.roles; 19 | if (typeof data !== 'object') { 20 | console.error('Invalid data received in the server response. Expected an object.'); 21 | return; 22 | } 23 | 24 | // Convert the object to an array 25 | const dataArray = Object.values(data); 26 | 27 | // Format the data into options array for react-select 28 | 29 | const formattedData = dataArray.map((role, index) => ({ value: role, label: role.charAt(0).toUpperCase() + role.slice(1) })); 30 | // Set the roles state with formatted data 31 | set({roles: formattedData,rolesLoaded:true }); 32 | 33 | 34 | } catch (error) { 35 | console.error('Error:', error); 36 | } 37 | } 38 | })); 39 | 40 | export default useRolesData; 41 | 42 | -------------------------------------------------------------------------------- /settings/src/Settings/TwoFA/select.scss: -------------------------------------------------------------------------------- 1 | div[class$="MenuPortal"] { 2 | z-index:30; 3 | } -------------------------------------------------------------------------------- /settings/src/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | render, createRoot 3 | } from '@wordpress/element'; 4 | import Page from './Page'; 5 | 6 | /** 7 | * Initialize 8 | */ 9 | 10 | document.addEventListener( 'DOMContentLoaded', () => { 11 | const container = document.getElementById( 'really-simple-ssl' ); 12 | if ( container ) { 13 | if ( createRoot ) { 14 | createRoot( container ).render( <Page/> ); 15 | } else { 16 | render( <Page/>, container ); 17 | } 18 | } 19 | }); 20 | 21 | /* 22 | * Some oldschool stuff 23 | */ 24 | 25 | document.addEventListener('click', e => { 26 | if ( e.target.closest('#ssl-labs-check-button') ) { 27 | document.querySelector('.rsssl-ssllabs').classList.add('rsssl-block-highlight'); 28 | setTimeout(function(){ 29 | document.querySelector('.rsssl-ssllabs').classList.remove('rsssl-block-highlight'); 30 | }, 6000); 31 | } 32 | }); 33 | 34 | -------------------------------------------------------------------------------- /settings/src/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. ?> 2 | -------------------------------------------------------------------------------- /settings/src/utils/AddUrlRef.js: -------------------------------------------------------------------------------- 1 | export const addUrlRef = (url) => { 2 | const ref = rsssl_settings.ref; 3 | if ( parseInt(ref) > 0 ) { 4 | const [baseUrl, hash] = url.split('#'); 5 | const separator = baseUrl.includes('?') ? '&' : '?'; 6 | url = `${baseUrl}${separator}ref=${ref}${hash ? `#${hash}` : ''}`; 7 | } 8 | return url; 9 | } -------------------------------------------------------------------------------- /settings/src/utils/ErrorBoundary.js: -------------------------------------------------------------------------------- 1 | import { Component } from '@wordpress/element'; 2 | import PropTypes from 'prop-types'; 3 | 4 | class ErrorBoundary extends Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { hasError: false, error: null, errorInfo: null }; 8 | this.resetError = this.resetError.bind(this); 9 | } 10 | 11 | static getDerivedStateFromError(error) { 12 | return { hasError: true }; 13 | } 14 | 15 | componentDidCatch(error, errorInfo) { 16 | this.setState({ error, errorInfo }); 17 | // You can also log the error to an error reporting service 18 | console.log('ErrorBoundary', error, errorInfo); 19 | } 20 | 21 | resetError() { 22 | this.setState({ hasError: false, error: null, errorInfo: null }); 23 | } 24 | 25 | render() { 26 | if (this.state.hasError) { 27 | return ( 28 | <div> 29 | <h1>Something went wrong.</h1> 30 | 31 | {/* You can render any custom fallback UI */} 32 | <p>{this.props.fallback}</p> 33 | <button onClick={this.resetError}>Try Again</button> 34 | </div> 35 | ); 36 | } 37 | 38 | return this.props.children; 39 | } 40 | } 41 | 42 | ErrorBoundary.propTypes = { 43 | children: PropTypes.node, 44 | fallback: PropTypes.node, 45 | }; 46 | 47 | export default ErrorBoundary; -------------------------------------------------------------------------------- /settings/src/utils/Flag/Flag.js: -------------------------------------------------------------------------------- 1 | import * as Flags from './Flags'; 2 | 3 | const Flag = ({ countryCode, style, title }) => { 4 | const FlagComponent = Flags[countryCode]; 5 | return FlagComponent ? <span title={title} ><FlagComponent style={style} /></span> : ( 6 | <span title={title}>{countryCode}</span> 7 | ); 8 | }; 9 | 10 | export default Flag; -------------------------------------------------------------------------------- /settings/src/utils/Hyperlink.js: -------------------------------------------------------------------------------- 1 | const Hyperlink = (props) => { 2 | let label_pre = ''; 3 | let label_post = ''; 4 | let link_text = ''; 5 | 6 | // Split the text around '%s' if it exists 7 | if (props.text.indexOf('%s') !== -1) { 8 | let parts = props.text.split(/%s/); 9 | label_pre = parts[0]; 10 | link_text = parts[1]; 11 | label_post = parts[2]; 12 | } else { 13 | link_text = props.text; 14 | } 15 | 16 | // Use the passed className or default to 'rsssl-link' 17 | let className = props.className ? props.className : 'rsssl-link'; 18 | 19 | // Include rel attribute in the anchor tag 20 | return ( 21 | <> 22 | {label_pre} 23 | <a 24 | className={className} 25 | target={props.target} 26 | rel={props.rel} // Add the rel attribute here 27 | href={props.url} 28 | > 29 | {link_text} 30 | </a> 31 | {label_post} 32 | </> 33 | ); 34 | } 35 | 36 | export default Hyperlink; -------------------------------------------------------------------------------- /settings/src/utils/autoCompleteTheme.js: -------------------------------------------------------------------------------- 1 | // theme.js 2 | import { createTheme } from '@mui/material/styles'; 3 | 4 | const autoCompleteSharedTheme = createTheme({ 5 | typography: { 6 | fontSize: 12, 7 | fontFamily: 'inherit', 8 | }, 9 | components: { 10 | MuiAutocomplete: { 11 | styleOverrides: { 12 | inputRoot: { 13 | '& .MuiAutocomplete-input': { 14 | border: 0, 15 | }, 16 | flexWrap: 'inherit', 17 | }, 18 | popper: { 19 | fontSize: '12px', 20 | }, 21 | paper: { 22 | fontSize: '12px', 23 | }, 24 | option: { 25 | fontSize: '12px', 26 | }, 27 | }, 28 | }, 29 | MuiInputBase: { 30 | styleOverrides: { 31 | root: { 32 | fontSize: '12px', 33 | fontFamily: 'inherit', 34 | height: '40px', 35 | }, 36 | }, 37 | }, 38 | MuiList: { 39 | styleOverrides: { 40 | root: { 41 | fontSize: '8px', 42 | }, 43 | }, 44 | }, 45 | }, 46 | }); 47 | 48 | export default autoCompleteSharedTheme; -------------------------------------------------------------------------------- /settings/src/utils/lib.js: -------------------------------------------------------------------------------- 1 | export const in_array = (needle, haystack) => { 2 | let length = haystack.length; 3 | for(let i = 0; i < length; i++) { 4 | if( haystack[i] == needle ) return true; 5 | 6 | } 7 | return false; 8 | } 9 | 10 | export const errorMsg = (error) => { 11 | let length = haystack.length; 12 | for(let i = 0; i < length; i++) { 13 | if( haystack[i] == needle ) return true; 14 | 15 | } 16 | return false; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /settings/src/utils/sleeper.js: -------------------------------------------------------------------------------- 1 | /* 2 | * helper function to delay after a promise 3 | * @param ms 4 | * @returns {function(*): Promise<unknown>} 5 | */ 6 | const sleeper = (ms) => { 7 | return function(x) { 8 | return new Promise(resolve => setTimeout(() => resolve(x), ms)); 9 | }; 10 | } 11 | export default sleeper; -------------------------------------------------------------------------------- /settings/webpack.config.js: -------------------------------------------------------------------------------- 1 | const defaultConfig = require("@wordpress/scripts/config/webpack.config"); 2 | 3 | module.exports = { 4 | ...defaultConfig, 5 | output: { 6 | ...defaultConfig.output, 7 | filename: '[name].[contenthash].js', 8 | chunkFilename: '[name].[contenthash].js', 9 | }, 10 | resolve: { 11 | ...defaultConfig.resolve, 12 | fallback: { 13 | "path": require.resolve("path-browserify"), 14 | }, 15 | }, 16 | module: { 17 | ...defaultConfig.module, 18 | rules: [ 19 | ...defaultConfig.module.rules, 20 | { 21 | test: /\.node$/, 22 | loader: 'node-loader', 23 | }, 24 | ], 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /testssl/cloudflare/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"' 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/cloudflare/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/cloudfront/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{HTTP:CloudFront-Forwarded-Proto} !https 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/cloudfront/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/envhttps/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{ENV:HTTPS} !=on 4 | RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/envhttps/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/loadbalancer/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{HTTP:X-Forwarded-Proto} !https 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/loadbalancer/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/serverhttps1/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{HTTPS} !=1 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/serverhttps1/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/serverhttpson/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{HTTPS} !=on [NC] 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/serverhttpson/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/serverhttpxforwardedssl1/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{HTTP:X-Forwarded-SSL} !=1 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/serverhttpxforwardedssl1/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/serverhttpxforwardedsslon/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{HTTP:X-Forwarded-SSL} !on 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/serverhttpxforwardedsslon/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/serverhttpxproto/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{HTTP:X-Proto} !SSL 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/serverhttpxproto/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /testssl/serverport443/.htaccess: -------------------------------------------------------------------------------- 1 | <IfModule mod_rewrite.c> 2 | RewriteEngine on 3 | RewriteCond %{SERVER_PORT} !443 4 | RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 5 | </IfModule> 6 | -------------------------------------------------------------------------------- /testssl/serverport443/ssl-test-page.html: -------------------------------------------------------------------------------- 1 | <html> 2 | <head> 3 | <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"> 4 | </head> 5 | <body> 6 | This page is for testing SSL functionality. 7 | #SSL TEST PAGE# 8 | </body> 9 | </html> 10 | -------------------------------------------------------------------------------- /upgrade/ajax.js: -------------------------------------------------------------------------------- 1 | 2 | var rsp_ajax = {}; 3 | 4 | rsp_ajax.x = function () { 5 | if (typeof XMLHttpRequest !== 'undefined') { 6 | return new XMLHttpRequest(); 7 | } 8 | var versions = [ 9 | "MSXML2.XmlHttp.6.0", 10 | "MSXML2.XmlHttp.5.0", 11 | "MSXML2.XmlHttp.4.0", 12 | "MSXML2.XmlHttp.3.0", 13 | "MSXML2.XmlHttp.2.0", 14 | "Microsoft.XmlHttp" 15 | ]; 16 | 17 | var xhr; 18 | for (var i = 0; i < versions.length; i++) { 19 | try { 20 | xhr = new ActiveXObject(versions[i]); 21 | break; 22 | } catch (e) { 23 | } 24 | } 25 | return xhr; 26 | }; 27 | 28 | rsp_ajax.send = function (url, callback, method, data, async) { 29 | if (async === undefined) { 30 | async = true; 31 | } 32 | var x = rsp_ajax.x(); 33 | x.open(method, url, async); 34 | x.onreadystatechange = function () { 35 | if (x.readyState == 4) { 36 | callback(x.responseText) 37 | } 38 | }; 39 | if (method == 'POST') { 40 | x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 41 | } 42 | x.send(data) 43 | }; 44 | 45 | rsp_ajax.get = function (url, data, callback, async) { 46 | var query = []; 47 | for (var key in data) { 48 | query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])); 49 | } 50 | rsp_ajax.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'GET', null, async) 51 | }; 52 | -------------------------------------------------------------------------------- /upgrade/ajax.min.js: -------------------------------------------------------------------------------- 1 | var rsp_ajax={};rsp_ajax.x=function(){if(typeof XMLHttpRequest!=="undefined"){return new XMLHttpRequest}var versions=["MSXML2.XmlHttp.6.0","MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"];var xhr;for(var i=0;i<versions.length;i++){try{xhr=new ActiveXObject(versions[i]);break}catch(e){}}return xhr};rsp_ajax.send=function(url,callback,method,data,async){if(async===undefined){async=true}var x=rsp_ajax.x();x.open(method,url,async);x.onreadystatechange=function(){if(x.readyState==4){callback(x.responseText)}};if(method=="POST"){x.setRequestHeader("Content-type","application/x-www-form-urlencoded")}x.send(data)};rsp_ajax.get=function(url,data,callback,async){var query=[];for(var key in data){query.push(encodeURIComponent(key)+"="+encodeURIComponent(data[key]))}rsp_ajax.send(url+(query.length?"?"+query.join("&"):""),callback,"GET",null,async)}; -------------------------------------------------------------------------------- /upgrade/img/burst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/upgrade/img/burst.png -------------------------------------------------------------------------------- /upgrade/img/complianz-gdpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/upgrade/img/complianz-gdpr.png -------------------------------------------------------------------------------- /upgrade/img/really-simple-ssl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Really-Simple-Plugins/really-simple-ssl/449704cac9300e53239629dd8dbd07cbfd3601c4/upgrade/img/really-simple-ssl.png -------------------------------------------------------------------------------- /upgrade/index.php: -------------------------------------------------------------------------------- 1 | <?php // You don't belong here. 2 | --------------------------------------------------------------------------------