- add Filament toggle to control whether attendance check-in requires captcha
- persist the toggle under captcha.attendance.enabled with sensible defaults
Signed-off-by: Qi HU <github@spcsky.com>
- require a successful captcha challenge before recording the day’s attendance
- preserve the original attendance summary layout after a successful check-in
Signed-off-by: Qi HU <github@spcsky.com>
- adjust layout spacing on public auth-related templates
- ensure captcha challenge areas remain visible on small screens
- align image driver output with refreshed markup
Signed-off-by: Qi HU <github@spcsky.com>
Introduce a configurable captcha manager with drivers for image,
Cloudflare Turnstile, and Google reCAPTCHA, including fallback
behaviour.
Refactor login, signup, complain, and related flows to use the new
abstraction while simplifying the legacy image endpoint.
Document captcha environment options and restore classic defaults in
.env.example.
Signed-off-by: Qi HU <github@spcsky.com>
When we use `php artisan optimize` command, it will cause duplicate includes:
```
PHP Fatal error: Cannot redeclare function get_global_sp_state() (previously declared in include/globalfunctions.php:3) in include/globalfunctions.php on line 3
Symfony\Component\ErrorHandler\Error\FatalError
Cannot redeclare function get_global_sp_state() (previously declared in include/globalfunctions.php:3)
at include/globalfunctions.php:3
1▕ <?php
2▕
➜ 3▕ function get_global_sp_state()
4▕ {
5▕ static $global_promotion_state;
6▕ $cacheKey = \App\Models\Setting::TORRENT_GLOBAL_STATE_CACHE_KEY;
7▕ if (is_null($global_promotion_state)) {
8▕ $row = \Nexus\Database\NexusDB::remember($cacheKey, 600, function () use ($cacheKey) {
9▕ return \Nexus\Database\NexusDB::getOne('torrents_state', 1);
Whoops\Exception\ErrorException
Cannot redeclare function get_global_sp_state() (previously declared in include/globalfunctions.php:3)
at include/globalfunctions.php:3
1▕ <?php
2▕
➜ 3▕ function get_global_sp_state()
4▕ {
5▕ static $global_promotion_state;
6▕ $cacheKey = \App\Models\Setting::TORRENT_GLOBAL_STATE_CACHE_KEY;
7▕ if (is_null($global_promotion_state)) {
8▕ $row = \Nexus\Database\NexusDB::remember($cacheKey, 600, function () use ($cacheKey) {
9▕ return \Nexus\Database\NexusDB::getOne('torrents_state', 1);
+1 vendor frames
2 [internal]:0
Whoops\Run::handleShutdown()
```
So we should use `require_once` instead of `require` to avoid this issue.
Signed-off-by: Qi HU <github@spcsky.com>