Skip to content

Commit 40d0f2e

Browse files
committed
[#2422] Added 'reroute_email' module with environment-based settings.
1 parent ddd02ed commit 40d0f2e

116 files changed

Lines changed: 1113 additions & 186 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.vortex/docs/content/drupal/README.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ You would need to add more modules and themes once you finish the initial setup.
3232
| [`pathauto`](https://www.drupal.org/project/pathauto) | Automatically generates URL/path aliases for content. |
3333
| [`redirect`](https://www.drupal.org/project/redirect) | Provides URL redirection management. |
3434
| [`redis`](https://www.drupal.org/project/redis) | Integrates Redis caching backend. |
35+
| [`reroute_email`](https://www.drupal.org/project/reroute_email) | Intercepts outgoing emails and reroutes them to a configurable address. |
3536
| [`robotstxt`](https://www.drupal.org/project/robotstxt) | Manages the robots.txt file for controlling search engine crawler access. |
3637
| [`search_api`](https://www.drupal.org/project/search_api) | Provides a flexible framework for creating search pages. |
3738
| [`search_api_solr`](https://www.drupal.org/project/search_api_solr) | Integrates Apache Solr with Search API. |

.vortex/docs/content/drupal/settings.mdx

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,89 @@ Each settings file should:
253253

254254
</details>
255255

256+
#### Shield
257+
258+
[Shield](https://www.drupal.org/project/shield) restricts access to your site
259+
by requiring HTTP authentication credentials. **Vortex** configures Shield to
260+
protect non-production environments from public access while keeping production,
261+
local development, and CI environments accessible without authentication.
262+
263+
**Environment behavior:**
264+
265+
| Environment | Shield enabled | Reason |
266+
|-------------|----------------|-------------------------------------------------|
267+
| Local | No | No need for HTTP auth during local development |
268+
| CI | No | Automated tests must access the site freely |
269+
| Dev | **Yes** | Protects development environments from crawlers |
270+
| Stage | **Yes** | Protects staging environments from public access|
271+
| Prod | No | Production is publicly accessible |
272+
273+
**Environment variables:**
274+
275+
| Variable | Default | Purpose |
276+
|-----------------------|----------------------|-------------------------------------------|
277+
| `DRUPAL_SHIELD_USER` | | HTTP authentication username |
278+
| `DRUPAL_SHIELD_PASS` | | HTTP authentication password |
279+
| `DRUPAL_SHIELD_PRINT` | `Restricted access.` | Message shown in the authentication popup |
280+
281+
**Overriding default behavior:**
282+
283+
Set `DRUPAL_SHIELD_DISABLED` to any non-empty value to completely disable Shield
284+
in an environment where it would otherwise be enabled. This is useful for
285+
temporary access during debugging or when an environment does not require
286+
protection.
287+
288+
import ShieldModuleSettingsExample from '!!raw-loader!./../../../../web/sites/default/includes/modules/settings.shield.php';
289+
290+
<details>
291+
<summary>Example of the `Shield` module `settings.shield.php` file</summary>
292+
293+
<CodeBlock language="php">{ShieldModuleSettingsExample}</CodeBlock>
294+
295+
</details>
296+
297+
#### Reroute Email
298+
299+
[Reroute Email](https://www.drupal.org/project/reroute_email) intercepts
300+
outgoing emails and redirects them to a configurable address instead of the
301+
intended recipients. This prevents accidental email delivery to real users in
302+
non-production environments while still allowing email functionality to be
303+
tested.
304+
305+
**Environment behavior:**
306+
307+
| Environment | Rerouting enabled | Reason |
308+
|-------------|-------------------|---------------------------------------------------------------|
309+
| Local | No | Emails are typically not sent in local development |
310+
| CI | No | Automated tests do not send real emails |
311+
| Dev | **Yes** | Prevents accidental delivery to real users |
312+
| Stage | No | Stage may require real email delivery for UAT |
313+
| Prod | No | Production emails must reach actual recipients |
314+
315+
Rerouting is also enabled in any custom environments (e.g., PR environments)
316+
that do not match the standard environment types listed above.
317+
318+
**Environment variables:**
319+
320+
| Variable | Default | Purpose |
321+
|--------------------------------|------------------------------------|------------------------------------------------------|
322+
| `DRUPAL_REROUTE_EMAIL_ADDRESS` | `webmaster@your-site-domain.example` | Address to receive all rerouted emails |
323+
| `DRUPAL_REROUTE_EMAIL_ALLOWED` | `*@your-site-domain.example` | Pattern for addresses allowed to bypass rerouting |
324+
325+
**Overriding default behavior:**
326+
327+
Set `DRUPAL_REROUTE_EMAIL_DISABLED` to any non-empty value to completely disable
328+
email rerouting in an environment where it would otherwise be enabled.
329+
330+
import RerouteEmailModuleSettingsExample from '!!raw-loader!./../../../../web/sites/default/includes/modules/settings.reroute_email.php';
331+
332+
<details>
333+
<summary>Example of the `Reroute Email` module `settings.reroute_email.php` file</summary>
334+
335+
<CodeBlock language="php">{RerouteEmailModuleSettingsExample}</CodeBlock>
336+
337+
</details>
338+
256339
### Local overrides
257340

258341
At the end of the `settings.php`, there is an option to include additional local

.vortex/docs/content/features.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
### Admin modules
4444

4545
- [Environment indicator](https://www.drupal.org/project/environment_indicator) for visual identification
46+
- [Reroute Email](https://www.drupal.org/project/reroute_email) for email interception in non-production environments
4647
- [Shield](https://www.drupal.org/project/shield) for HTTP authentication
4748
- [Stage file proxy](https://www.drupal.org/project/stage_file_proxy) for development efficiency
4849
- Configuration for [Search API](https://www.drupal.org/project/search_api) ([Solr](https://www.drupal.org/project/search_api_solr))

.vortex/installer/src/Prompts/Handlers/Modules.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ public static function getAvailableModules(): array {
130130
'environment_indicator' => 'Environment indicator',
131131
'pathauto' => 'Pathauto',
132132
'redirect' => 'Redirect',
133+
'reroute_email' => 'Reroute email',
133134
'robotstxt' => 'Robots.txt',
134135
'seckit' => 'Seckit',
135136
'shield' => 'Shield',

.vortex/installer/tests/Fixtures/handler_process/_baseline/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"drupal/pathauto": "__VERSION__",
2121
"drupal/redirect": "__VERSION__",
2222
"drupal/redis": "__VERSION__",
23+
"drupal/reroute_email": "__VERSION__",
2324
"drupal/robotstxt": "__VERSION__",
2425
"drupal/search_api": "__VERSION__",
2526
"drupal/search_api_solr": "__VERSION__",

.vortex/installer/tests/Fixtures/handler_process/_baseline/scripts/custom/provision-10-example.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ if echo "${environment}" | grep -q -e dev -e stage -e ci -e local; then
3838
drush php:eval "\Drupal::service('config.factory')->getEditable('system.site')->set('name', 'star wars')->save();"
3939

4040
task "Installing contrib modules."
41-
drush pm:install admin_toolbar coffee config_split config_update media environment_indicator pathauto redirect robotstxt shield stage_file_proxy xmlsitemap
41+
drush pm:install admin_toolbar coffee config_split config_update media environment_indicator pathauto redirect reroute_email robotstxt shield stage_file_proxy xmlsitemap
4242

4343
task "Installing Redis module."
4444
drush pm:install redis || true

.vortex/installer/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ public function testEnvironmentNoOverrides(): void {
7979
$config['shield.settings']['shield_enable'] = TRUE;
8080
$config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE;
8181
$config['xmlsitemap_engines.settings']['submit'] = FALSE;
82+
$config['reroute_email.settings']['enable'] = TRUE;
83+
$config['reroute_email.settings']['address'] = 'webmaster@star-wars.com';
84+
$config['reroute_email.settings']['allowed'] = '*@star-wars.com';
8285
$config['system.performance']['cache']['page']['max_age'] = 900;
8386
$this->assertConfig($config);
8487

@@ -153,6 +156,9 @@ public function testEnvironmentOverrides(): void {
153156
$config['shield.settings']['shield_enable'] = TRUE;
154157
$config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE;
155158
$config['xmlsitemap_engines.settings']['submit'] = FALSE;
159+
$config['reroute_email.settings']['enable'] = TRUE;
160+
$config['reroute_email.settings']['address'] = 'webmaster@star-wars.com';
161+
$config['reroute_email.settings']['allowed'] = '*@star-wars.com';
156162
$config['system.performance']['cache']['page']['max_age'] = 1800;
157163
$this->assertConfig($config);
158164

@@ -202,6 +208,9 @@ public function testEnvironmentLocal(): void {
202208
$config['xmlsitemap_engines.settings']['submit'] = FALSE;
203209
$config['system.logging']['error_level'] = 'all';
204210
$config['system.performance']['cache']['page']['max_age'] = 900;
211+
$config['reroute_email.settings']['enable'] = FALSE;
212+
$config['reroute_email.settings']['address'] = 'webmaster@star-wars.com';
213+
$config['reroute_email.settings']['allowed'] = '*@star-wars.com';
205214
$config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE;
206215
$config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE;
207216
$this->assertConfig($config);
@@ -251,6 +260,9 @@ public function testEnvironmentLocalContainer(): void {
251260
$config['xmlsitemap_engines.settings']['submit'] = FALSE;
252261
$config['system.logging']['error_level'] = 'all';
253262
$config['system.performance']['cache']['page']['max_age'] = 900;
263+
$config['reroute_email.settings']['enable'] = FALSE;
264+
$config['reroute_email.settings']['address'] = 'webmaster@star-wars.com';
265+
$config['reroute_email.settings']['allowed'] = '*@star-wars.com';
254266
$config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE;
255267
$config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE;
256268
$this->assertConfig($config);
@@ -302,6 +314,9 @@ public function testEnvironmentGha(): void {
302314
$config['xmlsitemap_engines.settings']['submit'] = FALSE;
303315
$config['system.logging']['error_level'] = 'all';
304316
$config['system.performance']['cache']['page']['max_age'] = 900;
317+
$config['reroute_email.settings']['enable'] = FALSE;
318+
$config['reroute_email.settings']['address'] = 'webmaster@star-wars.com';
319+
$config['reroute_email.settings']['allowed'] = '*@star-wars.com';
305320
$config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE;
306321
$config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE;
307322
$this->assertConfig($config);

.vortex/installer/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,145 @@ public static function dataProviderShield(): \Iterator {
665665
];
666666
}
667667

668+
/**
669+
* Test Reroute Email config.
670+
*/
671+
#[DataProvider('dataProviderRerouteEmail')]
672+
public function testRerouteEmail(string $env, array $vars, array $expected_present, array $expected_absent = []): void {
673+
$this->setEnvVars($vars + ['DRUPAL_ENVIRONMENT' => $env]);
674+
675+
$this->requireSettingsFile();
676+
677+
$this->assertConfigContains($expected_present);
678+
$this->assertConfigNotContains($expected_absent);
679+
}
680+
681+
/**
682+
* Data provider for testRerouteEmail().
683+
*/
684+
public static function dataProviderRerouteEmail(): \Iterator {
685+
// Local: disabled by default.
686+
yield [
687+
self::ENVIRONMENT_LOCAL,
688+
[],
689+
[
690+
'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'],
691+
],
692+
];
693+
694+
// CI: disabled by default.
695+
yield [
696+
self::ENVIRONMENT_CI,
697+
[],
698+
[
699+
'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'],
700+
],
701+
];
702+
703+
// Dev: enabled by default.
704+
yield [
705+
self::ENVIRONMENT_DEV,
706+
[],
707+
[
708+
'reroute_email.settings' => ['enable' => TRUE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'],
709+
],
710+
];
711+
712+
// SUT: enabled by default.
713+
yield [
714+
self::ENVIRONMENT_SUT,
715+
[],
716+
[
717+
'reroute_email.settings' => ['enable' => TRUE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'],
718+
],
719+
];
720+
721+
// Stage: disabled by default.
722+
yield [
723+
self::ENVIRONMENT_STAGE,
724+
[],
725+
[
726+
'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'],
727+
],
728+
];
729+
730+
// Prod: disabled by default.
731+
yield [
732+
self::ENVIRONMENT_PROD,
733+
[],
734+
[
735+
'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'],
736+
],
737+
];
738+
739+
// Dev with DRUPAL_REROUTE_EMAIL_DISABLED: forced off.
740+
yield [
741+
self::ENVIRONMENT_DEV,
742+
[
743+
'DRUPAL_REROUTE_EMAIL_DISABLED' => 1,
744+
],
745+
[
746+
'reroute_email.settings' => ['enable' => FALSE],
747+
],
748+
];
749+
750+
// SUT with DRUPAL_REROUTE_EMAIL_DISABLED: forced off.
751+
yield [
752+
self::ENVIRONMENT_SUT,
753+
[
754+
'DRUPAL_REROUTE_EMAIL_DISABLED' => 1,
755+
],
756+
[
757+
'reroute_email.settings' => ['enable' => FALSE],
758+
],
759+
];
760+
761+
// Custom address and allowed list.
762+
yield [
763+
self::ENVIRONMENT_DEV,
764+
[
765+
'DRUPAL_REROUTE_EMAIL_ADDRESS' => 'dev@example.com',
766+
'DRUPAL_REROUTE_EMAIL_ALLOWED' => '*@example.com',
767+
],
768+
[
769+
'reroute_email.settings' => ['enable' => TRUE, 'address' => 'dev@example.com', 'allowed' => '*@example.com'],
770+
],
771+
];
772+
773+
// DRUPAL_REROUTE_EMAIL_DISABLED with empty value: not disabled.
774+
yield [
775+
self::ENVIRONMENT_DEV,
776+
[
777+
'DRUPAL_REROUTE_EMAIL_DISABLED' => '',
778+
],
779+
[
780+
'reroute_email.settings' => ['enable' => TRUE],
781+
],
782+
];
783+
784+
// DRUPAL_REROUTE_EMAIL_DISABLED with 0: not disabled.
785+
yield [
786+
self::ENVIRONMENT_DEV,
787+
[
788+
'DRUPAL_REROUTE_EMAIL_DISABLED' => 0,
789+
],
790+
[
791+
'reroute_email.settings' => ['enable' => TRUE],
792+
],
793+
];
794+
795+
// DRUPAL_REROUTE_EMAIL_DISABLED with string '1': disabled.
796+
yield [
797+
self::ENVIRONMENT_DEV,
798+
[
799+
'DRUPAL_REROUTE_EMAIL_DISABLED' => '1',
800+
],
801+
[
802+
'reroute_email.settings' => ['enable' => FALSE],
803+
],
804+
];
805+
}
806+
668807
/**
669808
* Test Stage File Proxy config.
670809
*/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Reroute email settings.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
// Default reroute email address and allowed list.
11+
$config['reroute_email.settings']['address'] = getenv('DRUPAL_REROUTE_EMAIL_ADDRESS') ?: 'webmaster@star-wars.com';
12+
$config['reroute_email.settings']['allowed'] = getenv('DRUPAL_REROUTE_EMAIL_ALLOWED') ?: '*@star-wars.com';
13+
14+
// Enable rerouting in all environments except local, ci, stage and prod.
15+
// This covers dev and any custom environments (e.g., PR environments).
16+
if (!in_array($settings['environment'], [ENVIRONMENT_LOCAL, ENVIRONMENT_CI, ENVIRONMENT_STAGE, ENVIRONMENT_PROD])) {
17+
$config['reroute_email.settings']['enable'] = TRUE;
18+
}
19+
else {
20+
$config['reroute_email.settings']['enable'] = FALSE;
21+
}
22+
23+
// Allow to disable reroute email completely in the environment.
24+
if (!empty(getenv('DRUPAL_REROUTE_EMAIL_DISABLED'))) {
25+
$config['reroute_email.settings']['enable'] = FALSE;
26+
}

.vortex/installer/tests/Fixtures/handler_process/ciprovider_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@@ -280,9 +280,9 @@
1+
@@ -292,9 +292,9 @@
22
}
33

44
/**

0 commit comments

Comments
 (0)