tourze / idle-lock-screen-bundle
Symfony bundle for idle user lock screen functionality
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:symfony-bundle
pkg:composer/tourze/idle-lock-screen-bundle
Requires
- php: ^8.1
- doctrine/collections: ^2.3
- doctrine/dbal: ^4.0
- doctrine/doctrine-bundle: ^2.13
- doctrine/orm: ^3.0
- doctrine/persistence: ^3.1 || ^4
- symfony/config: ^6.4
- symfony/dependency-injection: ^6.4
- symfony/doctrine-bridge: ^6.4
- symfony/event-dispatcher: ^6.4
- symfony/framework-bundle: ^6.4
- symfony/http-foundation: ^6.4
- symfony/http-kernel: ^6.4
- symfony/routing: ^6.4
- symfony/security-bundle: ^6.4
- symfony/security-core: ^6.4
- symfony/yaml: ^6.4 || ^7.1
- twig/twig: ^3.13|^4.0
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-11-01 19:17:38 UTC
README
A Symfony bundle that provides automatic idle lock screen functionality. When users are inactive on sensitive pages for a configured period, the application automatically redirects them to a password verification screen.
Table of Contents
- Features
- Installation
- Quick Start
- Configuration
- API Reference
- Security
- Troubleshooting
- License
- Contributing
Features
- ✅ Route-based Configuration: Configure lock rules based on route patterns with wildcard and regex support
- ✅ Flexible Timeout Settings: Configurable idle timeout periods (1-86400 seconds)
- ✅ Smart Activity Detection: Automatically detects user activity (mouse, keyboard, touch events)
- ✅ Server-side Session Management: Lock state persisted server-side to prevent client-side bypassing
- ✅ Complete Audit Logging: Full logging of all lock/unlock operations for security auditing
- ✅ Non-intrusive Integration: Simple one-line template integration
- ✅ Modern UI: Clean, responsive lock screen interface
- ✅ Security Features: Protection against open redirect attacks and bypass attempts
- ✅ Mobile Friendly: Responsive design for mobile devices
Installation
1. Install via Composer
composer require tourze/idle-lock-screen-bundle
2. Register the Bundle
Add to config/bundles.php:
return [ // ... Tourze\IdleLockScreenBundle\IdleLockScreenBundle::class => ['all' => true], ];
3. Create Database Tables
Run database migrations:
php bin/console doctrine:migrations:diff php bin/console doctrine:migrations:migrate
Or create the table structure manually:
CREATE TABLE idle_lock_configuration ( id INT AUTO_INCREMENT NOT NULL, route_pattern VARCHAR(255) NOT NULL, timeout_seconds INT NOT NULL, is_enabled TINYINT(1) NOT NULL, description VARCHAR(500) DEFAULT NULL, created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)', updated_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)', PRIMARY KEY(id), INDEX idx_route_pattern (route_pattern), INDEX idx_is_enabled (is_enabled) ); CREATE TABLE idle_lock_record ( id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, session_id VARCHAR(128) NOT NULL, action_type VARCHAR(20) NOT NULL, route VARCHAR(255) NOT NULL, ip_address VARCHAR(45) DEFAULT NULL, user_agent LONGTEXT DEFAULT NULL, context JSON DEFAULT NULL, created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)', PRIMARY KEY(id), INDEX idx_user_id (user_id), INDEX idx_session_id (session_id), INDEX idx_action_type (action_type), INDEX idx_user_session (user_id, session_id) );
Quick Start
1. Template Integration
Add the idle lock script to your base template (e.g., templates/base.html.twig) before the closing </body> tag:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{% block title %}Welcome!{% endblock %}</title> </head> <body> {% block body %}{% endblock %} <!-- Add idle lock script at the bottom of the page --> {{ idle_lock_script() }} </body> </html>
2. Configure Lock Rules
Create lock configurations via code:
use Tourze\IdleLockScreenBundle\Service\IdleLockDetector; public function configureIdleLock(IdleLockDetector $detector): void { // Configure billing pages with 60-second timeout $detector->createConfiguration( routePattern: '/billing/*', timeoutSeconds: 60, isEnabled: true, description: 'Billing related pages' ); // Configure admin panel with 30-second timeout $detector->createConfiguration( routePattern: '^/admin/.*', timeoutSeconds: 30, isEnabled: true, description: 'Admin panel pages' ); }
3. Route Pattern Syntax
The bundle supports three pattern matching modes:
Exact Match
/billing/invoice
Wildcard Match
/billing/* # Matches all single-level paths under /billing/
/billing/** # Matches all multi-level paths under /billing/
Regular Expression Match
^/admin/.* # Matches all paths starting with /admin/
/billing/(invoice|payment) # Matches /billing/invoice or /billing/payment
Configuration
Programmatic Configuration
use Tourze\IdleLockScreenBundle\Service\IdleLockDetector; // In a controller or service public function setupLockRules(IdleLockDetector $detector): void { // Create a new configuration $config = $detector->createConfiguration( routePattern: '/sensitive-area/*', timeoutSeconds: 120, isEnabled: true, description: 'Sensitive area requiring frequent verification' ); // Check if a route should be locked $shouldLock = $detector->shouldLockRoute('/billing/invoice'); // Get configuration for a specific route $config = $detector->getRouteConfiguration('/billing/invoice'); }
Database Configuration
Insert configurations directly into the database:
INSERT INTO idle_lock_configuration (route_pattern, timeout_seconds, is_enabled, description, created_at, updated_at) VALUES ('/billing/*', 60, 1, 'Billing related pages', NOW(), NOW()), ('/account/sensitive', 30, 1, 'Sensitive account pages', NOW(), NOW()), ('^/admin/.*', 30, 1, 'Admin panel pages', NOW(), NOW());
API Reference
Twig Functions
idle_lock_script()
Renders the idle lock JavaScript code. Only outputs the script when the current route has lock enabled and the session is not locked.
is_idle_lock_enabled()
Checks if idle lock is enabled for the current route.
idle_lock_timeout()
Gets the timeout duration in seconds for the current route.
Example usage in templates:
{% if is_idle_lock_enabled() %}
<div class="alert alert-info">
This page has idle lock enabled. Timeout: {{ idle_lock_timeout() }} seconds
</div>
{% endif %}
Services
IdleLockDetector
Service for managing lock configurations.
// Check if a route should be locked $shouldLock = $detector->shouldLockRoute('/billing/invoice'); // Get route configuration $config = $detector->getRouteConfiguration('/billing/invoice'); // Create new configuration $config = $detector->createConfiguration('/new-route/*', 60);
LockManager
Service for managing lock state.
// Lock the session $lockManager->lockSession('/billing/invoice', 'idle_timeout'); // Unlock the session $lockManager->unlockSession(); // Check lock status $isLocked = $lockManager->isSessionLocked(); // Get user lock history $history = $lockManager->getUserLockHistory();
RoutePatternMatcher
Service for pattern matching.
// Check if route matches pattern $matches = $matcher->matches('/billing/invoice', '/billing/*'); // Validate pattern syntax $isValid = $matcher->isValidPattern('^/admin/.*');
Security
- Password Verification: Implement secure password verification logic
- Session Security: Lock state is stored server-side and cannot be tampered with by clients
- Redirect Security: Built-in protection against open redirect attacks
- Audit Logging: Complete logging of all lock-related operations for security auditing
Custom Password Verification
You can customize the password verification logic by extending the unlock controller:
use Tourze\IdleLockScreenBundle\Controller\IdleLockScreenUnlockController; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; class CustomUnlockController extends IdleLockScreenUnlockController { public function __construct( // ... parent constructor parameters private UserPasswordHasherInterface $passwordHasher ) { parent::__construct(/* ... */); } // Override password verification logic protected function verifyPassword(string $password): bool { $user = $this->security->getUser(); if (!$user) { return false; } return $this->passwordHasher->isPasswordValid($user, $password); } }
Troubleshooting
Script Not Injected
Ensure you've called {{ idle_lock_script() }} in your template and the current route has lock configuration enabled.
Lock Not Working
- Check if the route pattern correctly matches the current route
- Verify the configuration is enabled (
is_enabled = true) - Check browser console for JavaScript errors
Cannot Unlock
- Verify password verification logic is correctly implemented
- Check if user session is valid
License
MIT License
Contributing
Issues and Pull Requests are welcome!