redbitcz / debug-mode-enabler
Debug mode enabler - safe and clean way to manage Debug Mode in your App
Installs: 2 276
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 3
Forks: 2
Open Issues: 0
Requires
- php: ~8.0
- ext-json: *
- nette/utils: ^3.0 || ^4.0
Requires (Dev)
- firebase/php-jwt: ^5.0 || ^6.0 || dev-main
- nette/tester: ^2.5 || dev-master
- phpstan/phpstan: 1.12.6
Suggests
- firebase/php-jwt: Optional, required for SignedUrl plugin, compatible with version 5.x and 6.x
README
Safe and clean way to manage Debug Mode in your app by specific environment and/or manually in App. Package automatically detects development environments and provide secure way to temporary switch Debug Mode of your App at any environment.
Features
Package allows your app to switch to Debug Mode:
- automatically on localhost's environment by IP,
- semi-automatically on any environment where you set
APP_DEBUG
environment variable (useful for Docker dev-stack), - semi-automatically disable Debug mode on any environment where you set
app-debug-mode
cookie variable (useful for tests and similar cases), - manually enable/disable (force turn-on or turn-off) Debug Mode.
NOTE: Package does NOT provide any Debug tools directly – it only tells the app whether to switch to debug mode.
Package is optimized for invoking in very early lifecycle phase of your App
Requirements
Package requires:
- PHP version 8.0, 8.1, 8.2, 8.3 or 8.4
Enabler requires:
- Temporary directory with writable access
SignUrl plugin requires:
- Firebase JWT v5 or v6
Installation
composer require redbitcz/debug-mode-enabler
Using
Anywhere in your app you can determine if app is running in Debug mode by simple code:
$debugMode = \Redbitcz\DebugMode\Detector::detect(); //bool
It returns $debugMode
= true
when it detects Debug environment or manually switched.
Using with Nette
In Boostrap use package like in this example:
$debugModeDetector = new \Redbitcz\DebugMode\Detector(); $configurator = new Configurator(); $configurator->setDebugMode($debugModeDetector->isDebugMode());
I know, you love DI Container to build services like this. But Container Loader need to know Debug Mode state before is DI Container ready, you cannot use DI for Debug Mode detecting.
Using with Docker
If you are building custom Docker image for your devstack, add the environment variable APP_DEBUG=1
. For example in Dockerfile
file:
ENV APP_DEBUG 1
Avoid to publish these image to production!
Using with Docker compose
In your devstack set environment variable APP_DEBUG=1
. For example in docker-compose.yml
file:
environment: APP_DEBUG: 1
Manually switch
WARNING – DANGER ZONE: Following feature allows you to force Debug Mode on any environment, including production. Please use it with great caution only! Wrong use might cause critical security issue! Before using Enabler's feature, make sure your app is resistant to XSS, CSRF and similar attacks!
Enabler provide feature to force enable or disable Debug Mode anywhere for user's browser (drived by Cookie).
This example turn on Debug Mode for user's browser:
$enabler = new \Redbitcz\DebugMode\Enabler($tempDir); $detector = new \Redbitcz\DebugMode\Detector(\Redbitcz\DebugMode\Detector::MODE_FULL, $enabler); $enabler->activate(true);
Options
$enabler->activate(true)
- force to Debug Mode turn on,$enabler->activate(false)
- force to Debug Mode turn off,$enabler->deactivate()
- reset back to automatically detection by environment.
Using with Nette
Debug Mode Enabler (unlike Debug Mode Detector) can be simply served through DI Container with configuration in config.neon
:
services: - Redbitcz\DebugMode\Enabler(%tempDir%)
At most cases this example creates second instance of Enabler
class because first one is already created
internally with Detector
instance in Bootstrap
.
To re-use already existing instance you can inject it to DI Container:
$tempDir = __DIR__ . '/../temp'; $enabler = new \Redbitcz\DebugMode\Enabler($tempDir); $debugModeDetector = new \Redbitcz\DebugMode\Detector(\Redbitcz\DebugMode\Detector::MODE_FULL, $enabler); $configurator = new Configurator(); $configurator->setDebugMode($debugModeDetector->isDebugMode()); $configurator->addServices(['debugModeEnabler' => $debugModeDetector->getEnabler()]);
Don't forget letting know DI Container with service declaration in config.neon
:
services: debugModeEnabler: type: Redbitcz\DebugMode\Enabler imported: true
Plugins
Detector supports custom plugin. You can build custom plugin to provide your own roles to manage Debug Mode. Plugin must
implements Plugin
interface what means add __invoke()
method. That method is called always is Detector aksed to
detect mode.
Plugin retuns result of detection:
null
– no result – Detector will try to ask another plugin or detection method to decidetrue
– force turn-on debug mode for current requestfalse
– force turn-off debug mode for current request
Note: You should return null
value when Plugin doesn't explicitly matches rule. Boolean value is always stops
processing detection rules.
Don't do this:
if (…) { return true; } else { return false; }
instead return null
when your rule is not matched:
if (…) { return true; } else { return null; }
Your Plugin you can register to Detector with method appendPlugin()
or prepedndPlugin()
.
$detector = new \Redbitcz\DebugMode\Detector(); $plugin = new MyPlugin(); $detector->appendPlugin($plugin); $detector->isDebugMode(); // <---- this invoke all Plugins
SignUrl plugin
SignUrl
plugin provide secure way to share link with activated Debug Mode.
$plugin = \Redbitcz\DebugMode\Plugin\SignedUrl::create('secretkey', 'HS256', 'https://myapp.cz'); $detector->appendPlugin($plugin); $signedUrl = $plugin->signUrl('https://myapp.cz/failingPage', '+1 hour'); echo 'Private link with activated Debug mode: ' . htmlspecialchars($signedUrl, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE);
Security notes
Wrong usage of the SignUrl
plugin can open critical vulnerability issue at your App. Follow this instructions:
- Always create
SignUrl
with strong and Secret key, use key generator like:base64_encode(random_bytes(32))
- Always create
SignUrl
with specified$audience
parameter which distinguishes versions of app (stage vs production) to prevent unwanted re-using signatures between them (read more about importance of audience).
License
The MIT License (MIT). Please see License File for more information.