diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..e9a69d9 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.233.0/containers/ubuntu +{ + "name": "Ubuntu", + "image" : "mcr.microsoft.com/vscode/devcontainers/base:0-jammy", + "settings": {}, + "extensions": [], + "forwardPorts": [ 8080, 8081, 8082, 8083 ], + "postCreateCommand": "./.devcontainer/postCreateCommand.sh", + "postStartCommand": "./.devcontainer/postStartCommand.sh", + "features": { + "docker-in-docker": "latest" + } +} diff --git a/.devcontainer/postCreateCommand.sh b/.devcontainer/postCreateCommand.sh new file mode 100755 index 0000000..704cfd5 --- /dev/null +++ b/.devcontainer/postCreateCommand.sh @@ -0,0 +1,15 @@ +#!/bin/bash +if [ ! -z ${GITPOD_HOST+x} ]; then + WP_SITE_URL="https://8080-${GITPOD_WORKSPACE_ID}.${GITPOD_WORKSPACE_CLUSTER_HOST}" +elif [ ! -z ${CODESPACE_NAME+x} ]; then + WP_SITE_URL="https://${CODESPACE_NAME}-8080.githubpreview.dev" +else + WP_SITE_URL="http://localhost:8080" +fi + +docker run --rm --tty --volume $PWD:/app --user $(id -u):$(id -g) composer install --ignore-platform-reqs +docker-compose up -d +echo "Pausing for MySQL to complete..." && sleep 30 +docker-compose exec www wp core install --url="${WP_SITE_URL}" --title="SMTP Dummy" --admin_user="admin" --admin_password="password" --admin_email="code@soupbowl.io" --allow-root +docker-compose exec www wp plugin activate simple-smtp --allow-root +cp .env.example .env diff --git a/.devcontainer/postStartCommand.sh b/.devcontainer/postStartCommand.sh new file mode 100755 index 0000000..2a67cfd --- /dev/null +++ b/.devcontainer/postStartCommand.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker-compose up -d diff --git a/.distignore b/.distignore index 84e6214..a38ab1d 100644 --- a/.distignore +++ b/.distignore @@ -1,3 +1,4 @@ +/.devcontainer /.docker /.git /.github diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 2a578ae..7026d72 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -1,6 +1,8 @@ FROM docker.io/wordpress:php7.4-apache -RUN apt-get update && apt-get install less +RUN apt-get -y update && apt-get -y --no-install-recommends install less \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* RUN curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar --output /usr/bin/wp \ && chmod +X /usr/bin/wp \ diff --git a/.github/ISSUE_TEMPLATE/smtp_report.md b/.github/ISSUE_TEMPLATE/smtp_report.md index f465680..bcaa98c 100644 --- a/.github/ISSUE_TEMPLATE/smtp_report.md +++ b/.github/ISSUE_TEMPLATE/smtp_report.md @@ -1,5 +1,5 @@ --- -name: Report missing/incorrect SMTP settings +name: Report new, missing or incorrect SMTP settings about: Report issues with the Quick Config SMTP chooser. title: '' labels: smtp-setting diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 41bb031..22a07dd 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,6 +15,7 @@ jobs: dev: no args: --profile --ignore-platform-reqs - name: WordPress Plugin Deploy + id: deploy uses: 10up/action-wordpress-plugin-deploy@stable with: generate-zip: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1c41291..9e41c5f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,6 +4,11 @@ on: branches: - main - develop + paths-ignore: + - '.devcontainer/**' + - '.docker/**' + - '.github/**' + - '.vscode/**' pull_request: branches: - develop @@ -26,7 +31,7 @@ jobs: steps: - uses: actions/checkout@v2 - + - name: Composer Dependencies uses: php-actions/composer@v2 with: diff --git a/.gitpod.yml b/.gitpod.yml index 5e81a88..34126a8 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -4,14 +4,23 @@ tasks: docker pull composer docker-compose pull docker-compose build www - command: | - docker run --rm --tty --volume $PWD:/app --user $(id -u):$(id -g) composer install --ignore-platform-reqs - docker-compose up -d - echo "Pausing for MySQL to complete..."&& sleep 15 - docker-compose exec www wp core install --url="https://8080-${GITPOD_WORKSPACE_ID}.${GITPOD_WORKSPACE_CLUSTER_HOST}" --title="SMTP Dummy" --admin_user="admin" --admin_password="password" --admin_email="code@soupbowl.io" --allow-root - docker-compose exec www wp plugin activate simple-smtp --allow-root - cp .env.example .env + command: sh ./.devcontainer/postCreateCommand.sh vscode: extensions: - ms-azuretools.vscode-docker - johnbillion.vscode-wordpress-hooks + +ports: + - port: 8080 + name: WordPress + description: Main WordPress instance. + - port: 8081 + name: MailHog + description: Access GUI for the MailHog interface. + - port: 8082 + name: phpMyAdmin + description: Access GUI for the MariaDB instance. + - port: 8083 + description: SMTP port for MailHog. + - port: 4443 + description: Unused in GitPod. diff --git a/assets/smtp-config.js b/assets/smtp-config.js index 0c097fb..5eadee4 100644 --- a/assets/smtp-config.js +++ b/assets/smtp-config.js @@ -6,7 +6,7 @@ * @license MIT */ -const { __, _x, _n, _nx } = wp.i18n; +const { __ } = wp.i18n; /** * Grabs the sources file. If it loads, we continue. If not, we do not display this feature. diff --git a/docker-compose.yml b/docker-compose.yml index 3792cce..cb4a18a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.6' services: db: - image: docker.io/library/mariadb:latest + image: docker.io/library/mariadb:10.5.15 # Changed due to MariaDB Docker build issues. environment: MYSQL_ROOT_PASSWORD: s9f6sd759r32r7f0dsf5673894956 MYSQL_DATABASE: wordpress diff --git a/readme.txt b/readme.txt index 047cfec..f7dbcc2 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: mail,email,smtp,dispatch,sender Requires at least: 4.9 Tested up to: 6.0 Requires PHP: 7.0 -Stable tag: 1.3.1.1 +Stable tag: 1.3.2 License: MIT Adds a simple mail configuration panel into your WordPress installation. Supports temporary logging and config variables. @@ -95,7 +95,13 @@ To help diagnose disabled input boxes, when the WordPress site is in [debugging = Can I report an issue, or contribute to development? = Yes! [Please see our GitHub repository here](https://github.com/soup-bowl/wp-simple-smtp) for writing issues and/or making pull requests. +One of the easiest aspects to contribute to is the SMTP quick configuration segment. If you wish to maintain this aspect, suggest a new setting, or report broken entries, see the [SMTP quick config wiki page](https://github.com/soup-bowl/wp-simple-smtp/wiki/SMTP-Quick-Config). + == Changelog == += 1.3.2 = +* Added: Mail view now displays from, cc, bcc & the headers stored when logging is enabled. +* Fix: Infinite loop when a plugin hooks into the mail routine functions and sends an email ([#116](https://github.com/soup-bowl/wp-simple-smtp/pull/116)). + = 1.3.1.1 = * Verified working with WordPress 6.0. diff --git a/src/log/class-log.php b/src/log/class-log.php index 36dc503..243a5a5 100644 --- a/src/log/class-log.php +++ b/src/log/class-log.php @@ -121,6 +121,33 @@ public function get_recipients() { return $this->recipients; } + /** + * Gets the from details. + * + * @return string|null + */ + public function get_from() { + return $this->find_in_headers( 'from' ); + } + + /** + * Gets the cc recipients. + * + * @return string|null + */ + public function get_cc() { + return $this->find_in_headers( 'cc' ); + } + + /** + * Gets the bcc recipients. + * + * @return string|null + */ + public function get_bcc() { + return $this->find_in_headers( 'bcc' ); + } + /** * Gets the server dispatch headers. * @@ -130,6 +157,28 @@ public function get_headers() { return $this->headers; } + /** + * Same as get_headers, but the header strings are split. + * + * @param bool $exclude_recipients Remove CC from the list. + * @return array[] + */ + public function get_headers_as_array( $exclude_recipients = true ) { + $collection = []; + if ( ! empty( $this->get_headers() ) ) { + foreach ( $this->get_headers() as $header ) { + $expd = explode( ':', $header ); + if ( $exclude_recipients && in_array( strtolower( $expd[0] ), [ 'cc', 'bcc', 'from' ], true ) ) { + continue; + } else { + $collection[] = $expd; + } + } + } + + return $collection; + } + /** * The dispatch headers, unsplit. * @@ -273,4 +322,38 @@ public function set_timestamp( $timestamp ) { return $this; } + + /** + * Searches the header array for a particular header. + * + * @param string $needle Header to look for. + * @return string[] + */ + private function find_in_headers( $needle ) { + $collection = []; + foreach ( $this->get_headers_as_array( false ) as $header ) { + if ( strtolower( $header[0] ) === strtolower( $needle ) ) { + $collection[] = $header[1]; + } + } + + return $collection; + } + + /** + * Extracts the email from angled brackets, if the syntax is so. + * + * @param string $input The subject to be inspected. + * @return string Either the extracted email address, or the input is returned untouched. + */ + private function strip_email( $input ) { + $stripped = ''; + $rc = preg_match( '/(?<=\<).+?(?=\>)/', $input, $stripped ); + + if ( 1 === $rc ) { + return $stripped; + } else { + return $input; + } + } } diff --git a/src/log/class-logservice.php b/src/log/class-logservice.php index a3978b7..a41fd36 100644 --- a/src/log/class-logservice.php +++ b/src/log/class-logservice.php @@ -49,6 +49,7 @@ public function register_log_storage() { 'delete_post' => 'manage_options', 'read_post' => 'manage_options', ], + 'label' => _x( 'E-mail log entries', 'Post Type General Name', 'simple-smtp' ), ] ); } @@ -60,6 +61,12 @@ public function register_log_storage() { * @return integer ID of the newly-inserted entry. */ public function new_log_entry( $log ) { + // Patch fix to stop Sucuri from spamming the log. Should be investigated more. + $dup_check = post_exists( $log->get_subject(), '', current_time( 'mysql' ), $this->post_type ); + if ( 0 !== $dup_check ) { + return $dup_check; + } + $post_id = wp_insert_post( [ 'post_title' => $log->get_subject(), diff --git a/src/log/class-logtable.php b/src/log/class-logtable.php index d63f113..a6a7fcb 100644 --- a/src/log/class-logtable.php +++ b/src/log/class-logtable.php @@ -9,6 +9,7 @@ namespace wpsimplesmtp; +use wpsimplesmtp\Log; use wpsimplesmtp\LogService; /** @@ -68,13 +69,12 @@ public function display( $page, $maximum_per_page = 20 ) { if ( ! empty( $entries ) ) { foreach ( $entries as $entry ) { - $recipients = implode( ', ', $entry->get_recipients() ); $actions = $this->render_log_entry_buttons( $entry ); $date = gmdate( get_option( 'time_format' ) . ', ' . get_option( 'date_format' ), strtotime( $entry->get_timestamp() ) ); $row_classes = ( ! empty( $entry->get_error() ) ) ? 'site-archived log-row' : 'log-row'; echo wp_kses( ' - ' . $recipients . $actions . ' + ' . $this->display_recipients( $entry ) . $actions . ' ' . $entry->get_subject() . ' ' . $date . ' ' . $entry->get_error() . ' @@ -221,6 +221,33 @@ private function render_log_entry_buttons( $entry ) { return $row_actions; } + /** + * Compiles a list of recipients (to and cc) into a single string. + * + * @param Log $log_item Log entry item. + * @return string + */ + private function display_recipients( $log_item ) { + $recipients = []; + + if ( ! empty( $log_item->get_recipients() ) ) { + $recipients[] = esc_html__( 'To', 'simple-smtp' ) . ': ' . implode( ', ', $log_item->get_recipients() ); + } + + if ( ! empty( $log_item->get_cc() ) ) { + $recipients[] = esc_html__( 'CC', 'simple-smtp' ) . ': ' . implode( ', ', $log_item->get_cc() ); + } + + if ( ! empty( $log_item->get_bcc() ) ) { + $recipients[] = esc_html__( 'BCC', 'simple-smtp' ) . ': ' . implode( ', ', $log_item->get_bcc() ); + } + + return wp_kses( + implode( ', ', $recipients ), + $this->allowed_table_html() + ); + } + /** * Array for kses that allows table-related HTML only. * diff --git a/src/settings/class-mailview.php b/src/mail/class-mailview.php similarity index 60% rename from src/settings/class-mailview.php rename to src/mail/class-mailview.php index 580ce08..3b6dd27 100644 --- a/src/settings/class-mailview.php +++ b/src/mail/class-mailview.php @@ -47,8 +47,11 @@ public function render_email_view( $id ) { ) . '&resend'; if ( current_user_can( 'manage_options' ) && isset( $log ) ) { - $recipients = implode( ', ', $log->get_recipients() ); - $date = gmdate( get_option( 'time_format' ) . ', ' . get_option( 'date_format' ), strtotime( $log->get_timestamp() ) ); + $to = implode( ', ', $log->get_recipients() ); + $from = implode( ', ', $log->get_from() ); + $cc = implode( ', ', $log->get_cc() ); + $bcc = implode( ', ', $log->get_bcc() ); + $date = gmdate( get_option( 'time_format' ) . ', ' . get_option( 'date_format' ), strtotime( $log->get_timestamp() ) ); $content = ''; if ( ! empty( $log->get_headers() ) && false !== strpos( $log->get_headers_unified(), 'Content-Type: text\/html' ) ) { @@ -75,8 +78,51 @@ public function render_email_view( $id ) {
-
:
-
:
+ +
+ : +
+ + + +
+ : +
+ + + +
+ : +
+ + + +
+ : +
+ + +
+ : +
+ + get_headers() ) ) : ?> +
+ : +
    + get_headers_as_array() as $header ) : ?> +
  1. + + : + + + +
  2. + +
+
+ + get_attachments() ) ) : ?>
: @@ -110,7 +156,7 @@ public function render_email_view( $id ) {