Static files not generated on config import, only on form save
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3577557. -->
Reported by: [vzsigmond](https://www.drupal.org/user/698330)
Related to !1
>>>
<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>When the BotBuster module is deployed via config import (e.g. <code>drush config:import</code>), the static files required for DDoS protection are never generated. The module silently fails to protect any configured paths until an administrator manually re-saves the configuration form.</p>
<p>This is because the challenge HTML file (private://botbuster/challenge.html) and the protected paths JSON file (private://botbuster/protected-paths.json) are only generated inside <code>SecuritySettingsForm::submitForm()</code>, which is never executed during a config import.</p>
<h4 id="summary-steps-reproduce">Steps to reproduce</h4>
<p>1. Install the module and configure protected paths on a staging/local environment.<br>
2. Export configuration (<code>drush config:export</code>).<br>
3. On a different environment (e.g. production), import the configuration (<code>drush config:import</code>).<br>
4. Visit a protected path without a valid token.<br>
5. Expected: The browser verification challenge page is served.<br>
6. Actual: The request passes through unprotected. If DDoS protection is enabled but the challenge file is missing, a RuntimeException is thrown.</p>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<p>Replace the file generation logic in the form submit handler with a ConfigEvents::SAVE event subscriber. This subscriber listens for saves to botbuster.settings and regenerates both static files, regardless of whether the save originated from the admin form, config import, Drush, or any programmatic config change.</p>
<p>- Move <code>writeProtectedPathsFile(</code>) from the form into <code>ChallengeFileGenerator</code> so all file generation lives in one service.<br>
- Create <code>ConfigSaveSubscriber</code> that calls <code>generateChallengeFile()</code> and <code>writeProtectedPathsFile()</code> on every botbuster.settings config save.<br>
- Simplify <code>SecuritySettingsForm</code> to a pure config form with no injected services beyond what ConfigFormBase provides.<br>
- Remove <code>hook_install()</code> since the default config install already triggers <code>ConfigEvents::SAVE</code>, which now handles file generation automatically.</p>
issue