mirror of
https://github.com/pelican-dev/panel.git
synced 2025-06-07 23:28:59 +02:00
Captcha
This commit is contained in:
parent
09e3506efa
commit
4a89e75a09
43
app/Extensions/Captcha/CaptchaProvider.php
Normal file
43
app/Extensions/Captcha/CaptchaProvider.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Extensions\Captcha;
|
||||||
|
|
||||||
|
use App\Extensions\Captcha\Schemas\CaptchaSchemaInterface;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class CaptchaProvider
|
||||||
|
{
|
||||||
|
/** @var array<string, CaptchaSchemaInterface> */
|
||||||
|
private array $schemas = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, CaptchaSchemaInterface> | CaptchaSchemaInterface
|
||||||
|
*/
|
||||||
|
public function get(?string $id = null): array|CaptchaSchemaInterface
|
||||||
|
{
|
||||||
|
return $id ? $this->schemas[$id] : $this->schemas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function register(CaptchaSchemaInterface $schema): void
|
||||||
|
{
|
||||||
|
if (array_key_exists($schema->getId(), $this->schemas)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config()->set('captcha.' . Str::lower($schema->getId()), $schema->getConfig());
|
||||||
|
$this->schemas[$schema->getId()] = $schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Collection<CaptchaSchemaInterface> */
|
||||||
|
public function getActiveSchemas(): Collection
|
||||||
|
{
|
||||||
|
return collect($this->schemas)
|
||||||
|
->filter(fn (CaptchaSchemaInterface $schema) => $schema->isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getActiveSchema(): ?CaptchaSchemaInterface
|
||||||
|
{
|
||||||
|
return $this->getActiveSchemas()->first();
|
||||||
|
}
|
||||||
|
}
|
35
app/Extensions/Captcha/Schemas/CaptchaSchemaInterface.php
Normal file
35
app/Extensions/Captcha/Schemas/CaptchaSchemaInterface.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Extensions\Captcha\Schemas;
|
||||||
|
|
||||||
|
use Filament\Forms\Components\Component;
|
||||||
|
|
||||||
|
interface CaptchaSchemaInterface
|
||||||
|
{
|
||||||
|
public function getId(): string;
|
||||||
|
|
||||||
|
public function getName(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string|string[]|bool|null>
|
||||||
|
*/
|
||||||
|
public function getConfig(): array;
|
||||||
|
|
||||||
|
public function isEnabled(): bool;
|
||||||
|
|
||||||
|
public function getFormComponent(): Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Component[]
|
||||||
|
*/
|
||||||
|
public function getSettingsForm(): array;
|
||||||
|
|
||||||
|
public function getIcon(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string|bool>
|
||||||
|
*/
|
||||||
|
public function validateResponse(?string $captchaResponse = null): array;
|
||||||
|
|
||||||
|
public function verifyDomain(string $hostname, ?string $requestUrl = null): bool;
|
||||||
|
}
|
@ -1,45 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Extensions\Captcha\Providers;
|
namespace App\Extensions\Captcha\Schemas;
|
||||||
|
|
||||||
use Filament\Forms\Components\Component;
|
use Filament\Forms\Components\Component;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
use Illuminate\Foundation\Application;
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
abstract class CaptchaProvider
|
abstract class CommonSchema
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var array<string, static>
|
|
||||||
*/
|
|
||||||
protected static array $providers = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return self|static[]
|
|
||||||
*/
|
|
||||||
public static function get(?string $id = null): array|self
|
|
||||||
{
|
|
||||||
return $id ? static::$providers[$id] : static::$providers;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function __construct(protected Application $app)
|
|
||||||
{
|
|
||||||
if (array_key_exists($this->getId(), static::$providers)) {
|
|
||||||
if (!$this->app->runningUnitTests()) {
|
|
||||||
logger()->warning("Tried to create duplicate Captcha provider with id '{$this->getId()}'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
config()->set('captcha.' . Str::lower($this->getId()), $this->getConfig());
|
|
||||||
|
|
||||||
static::$providers[$this->getId()] = $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract public function getId(): string;
|
abstract public function getId(): string;
|
||||||
|
|
||||||
abstract public function getComponent(): Component;
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return Str::upper($this->getId());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string, string|string[]|bool|null>
|
* @return array<string, string|string[]|bool|null>
|
||||||
@ -83,34 +57,6 @@ abstract class CaptchaProvider
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getName(): string
|
|
||||||
{
|
|
||||||
return Str::title($this->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIcon(): ?string
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isEnabled(): bool
|
|
||||||
{
|
|
||||||
$id = Str::upper($this->getId());
|
|
||||||
|
|
||||||
return env("CAPTCHA_{$id}_ENABLED", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array<string, string|bool>
|
|
||||||
*/
|
|
||||||
public function validateResponse(?string $captchaResponse = null): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'message' => 'validateResponse not defined',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function verifyDomain(string $hostname, ?string $requestUrl = null): bool
|
public function verifyDomain(string $hostname, ?string $requestUrl = null): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
@ -1,11 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Filament\Components\Forms\Fields;
|
namespace App\Extensions\Captcha\Schemas\Turnstile;
|
||||||
|
|
||||||
use App\Rules\ValidTurnstileCaptcha;
|
|
||||||
use Filament\Forms\Components\Field;
|
use Filament\Forms\Components\Field;
|
||||||
|
|
||||||
class TurnstileCaptcha extends Field
|
class Component extends Field
|
||||||
{
|
{
|
||||||
protected string $viewIdentifier = 'turnstile';
|
protected string $viewIdentifier = 'turnstile';
|
||||||
|
|
||||||
@ -19,8 +18,6 @@ class TurnstileCaptcha extends Field
|
|||||||
|
|
||||||
$this->required();
|
$this->required();
|
||||||
|
|
||||||
$this->after(function (TurnstileCaptcha $component) {
|
$this->rule(new Rule());
|
||||||
$component->rule(new ValidTurnstileCaptcha());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,16 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Rules;
|
namespace App\Extensions\Captcha\Schemas\Turnstile;
|
||||||
|
|
||||||
use App\Extensions\Captcha\Providers\CaptchaProvider;
|
use App\Extensions\Captcha\CaptchaProvider;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Contracts\Validation\ValidationRule;
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
|
||||||
class ValidTurnstileCaptcha implements ValidationRule
|
class Rule implements ValidationRule
|
||||||
{
|
{
|
||||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||||
{
|
{
|
||||||
$response = CaptchaProvider::get('turnstile')->validateResponse($value);
|
$response = App::call(fn (CaptchaProvider $provider) => $provider->getActiveSchema()->validateResponse($value));
|
||||||
|
|
||||||
if (!$response['success']) {
|
if (!$response['success']) {
|
||||||
$fail($response['message'] ?? 'Unknown error occurred, please try again');
|
$fail($response['message'] ?? 'Unknown error occurred, please try again');
|
@ -1,26 +1,31 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Extensions\Captcha\Providers;
|
namespace App\Extensions\Captcha\Schemas\Turnstile;
|
||||||
|
|
||||||
use App\Filament\Components\Forms\Fields\TurnstileCaptcha;
|
use App\Extensions\Captcha\Schemas\CaptchaSchemaInterface;
|
||||||
|
use App\Extensions\Captcha\Schemas\CommonSchema;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Filament\Forms\Components\Component;
|
use Filament\Forms\Components\Component as BaseComponent;
|
||||||
use Filament\Forms\Components\Placeholder;
|
use Filament\Forms\Components\Placeholder;
|
||||||
use Filament\Forms\Components\Toggle;
|
use Filament\Forms\Components\Toggle;
|
||||||
use Illuminate\Foundation\Application;
|
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\HtmlString;
|
use Illuminate\Support\HtmlString;
|
||||||
|
|
||||||
class TurnstileProvider extends CaptchaProvider
|
class TurnstileSchema extends CommonSchema implements CaptchaSchemaInterface
|
||||||
{
|
{
|
||||||
public function getId(): string
|
public function getId(): string
|
||||||
{
|
{
|
||||||
return 'turnstile';
|
return 'turnstile';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getComponent(): Component
|
public function isEnabled(): bool
|
||||||
{
|
{
|
||||||
return TurnstileCaptcha::make('turnstile');
|
return env('CAPTCHA_TURNSTILE_ENABLED', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFormComponent(): BaseComponent
|
||||||
|
{
|
||||||
|
return Component::make('turnstile');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +39,7 @@ class TurnstileProvider extends CaptchaProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Component[]
|
* @return BaseComponent[]
|
||||||
*/
|
*/
|
||||||
public function getSettingsForm(): array
|
public function getSettingsForm(): array
|
||||||
{
|
{
|
||||||
@ -52,20 +57,14 @@ class TurnstileProvider extends CaptchaProvider
|
|||||||
->label(trans('admin/setting.captcha.info_label'))
|
->label(trans('admin/setting.captcha.info_label'))
|
||||||
->columnSpan(2)
|
->columnSpan(2)
|
||||||
->content(new HtmlString(trans('admin/setting.captcha.info'))),
|
->content(new HtmlString(trans('admin/setting.captcha.info'))),
|
||||||
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIcon(): string
|
public function getIcon(): ?string
|
||||||
{
|
{
|
||||||
return 'tabler-brand-cloudflare';
|
return 'tabler-brand-cloudflare';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function register(Application $app): self
|
|
||||||
{
|
|
||||||
return new self($app);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string, string|bool>
|
* @return array<string, string|bool>
|
||||||
*/
|
*/
|
@ -3,7 +3,7 @@
|
|||||||
namespace App\Filament\Admin\Pages;
|
namespace App\Filament\Admin\Pages;
|
||||||
|
|
||||||
use App\Extensions\Avatar\AvatarProvider;
|
use App\Extensions\Avatar\AvatarProvider;
|
||||||
use App\Extensions\Captcha\Providers\CaptchaProvider;
|
use App\Extensions\Captcha\CaptchaProvider;
|
||||||
use App\Extensions\OAuth\OAuthProvider;
|
use App\Extensions\OAuth\OAuthProvider;
|
||||||
use App\Models\Backup;
|
use App\Models\Backup;
|
||||||
use App\Notifications\MailTested;
|
use App\Notifications\MailTested;
|
||||||
@ -56,6 +56,8 @@ class Settings extends Page implements HasForms
|
|||||||
|
|
||||||
protected AvatarProvider $avatarProvider;
|
protected AvatarProvider $avatarProvider;
|
||||||
|
|
||||||
|
protected CaptchaProvider $captchaProvider;
|
||||||
|
|
||||||
/** @var array<mixed>|null */
|
/** @var array<mixed>|null */
|
||||||
public ?array $data = [];
|
public ?array $data = [];
|
||||||
|
|
||||||
@ -64,10 +66,11 @@ class Settings extends Page implements HasForms
|
|||||||
$this->form->fill();
|
$this->form->fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot(OAuthProvider $oauthProvider, AvatarProvider $avatarProvider): void
|
public function boot(OAuthProvider $oauthProvider, AvatarProvider $avatarProvider, CaptchaProvider $captchaProvider): void
|
||||||
{
|
{
|
||||||
$this->oauthProvider = $oauthProvider;
|
$this->oauthProvider = $oauthProvider;
|
||||||
$this->avatarProvider = $avatarProvider;
|
$this->avatarProvider = $avatarProvider;
|
||||||
|
$this->captchaProvider = $captchaProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function canAccess(): bool
|
public static function canAccess(): bool
|
||||||
@ -268,15 +271,14 @@ class Settings extends Page implements HasForms
|
|||||||
{
|
{
|
||||||
$formFields = [];
|
$formFields = [];
|
||||||
|
|
||||||
$captchaProviders = CaptchaProvider::get();
|
$captchaSchemas = $this->captchaProvider->get();
|
||||||
foreach ($captchaProviders as $captchaProvider) {
|
foreach ($captchaSchemas as $captchaSchema) {
|
||||||
$id = Str::upper($captchaProvider->getId());
|
$id = Str::upper($captchaSchema->getId());
|
||||||
$name = Str::title($captchaProvider->getId());
|
|
||||||
|
|
||||||
$formFields[] = Section::make($name)
|
$formFields[] = Section::make($captchaSchema->getName())
|
||||||
->columns(5)
|
->columns(5)
|
||||||
->icon($captchaProvider->getIcon() ?? 'tabler-shield')
|
->icon($captchaSchema->getIcon() ?? 'tabler-shield')
|
||||||
->collapsed(fn () => !env("CAPTCHA_{$id}_ENABLED", false))
|
->collapsed(fn () => !$captchaSchema->isEnabled())
|
||||||
->collapsible()
|
->collapsible()
|
||||||
->schema([
|
->schema([
|
||||||
Hidden::make("CAPTCHA_{$id}_ENABLED")
|
Hidden::make("CAPTCHA_{$id}_ENABLED")
|
||||||
@ -287,21 +289,14 @@ class Settings extends Page implements HasForms
|
|||||||
->visible(fn (Get $get) => $get("CAPTCHA_{$id}_ENABLED"))
|
->visible(fn (Get $get) => $get("CAPTCHA_{$id}_ENABLED"))
|
||||||
->label(trans('admin/setting.captcha.disable'))
|
->label(trans('admin/setting.captcha.disable'))
|
||||||
->color('danger')
|
->color('danger')
|
||||||
->action(function (Set $set) use ($id) {
|
->action(fn (Set $set) => $set("CAPTCHA_{$id}_ENABLED", false)),
|
||||||
$set("CAPTCHA_{$id}_ENABLED", false);
|
|
||||||
}),
|
|
||||||
FormAction::make("enable_captcha_$id")
|
FormAction::make("enable_captcha_$id")
|
||||||
->visible(fn (Get $get) => !$get("CAPTCHA_{$id}_ENABLED"))
|
->visible(fn (Get $get) => !$get("CAPTCHA_{$id}_ENABLED"))
|
||||||
->label(trans('admin/setting.captcha.enable'))
|
->label(trans('admin/setting.captcha.enable'))
|
||||||
->color('success')
|
->color('success')
|
||||||
->action(function (Set $set) use ($id, $captchaProviders) {
|
->action(fn (Set $set) => $set("CAPTCHA_{$id}_ENABLED", true)),
|
||||||
foreach ($captchaProviders as $captchaProvider) {
|
|
||||||
$loopId = Str::upper($captchaProvider->getId());
|
|
||||||
$set("CAPTCHA_{$loopId}_ENABLED", $loopId === $id);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
])->columnSpan(1),
|
])->columnSpan(1),
|
||||||
Group::make($captchaProvider->getSettingsForm())
|
Group::make($captchaSchema->getSettingsForm())
|
||||||
->visible(fn (Get $get) => $get("CAPTCHA_{$id}_ENABLED"))
|
->visible(fn (Get $get) => $get("CAPTCHA_{$id}_ENABLED"))
|
||||||
->columns(4)
|
->columns(4)
|
||||||
->columnSpan(4),
|
->columnSpan(4),
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace App\Filament\Pages\Auth;
|
namespace App\Filament\Pages\Auth;
|
||||||
|
|
||||||
use App\Events\Auth\ProvidedAuthenticationToken;
|
use App\Events\Auth\ProvidedAuthenticationToken;
|
||||||
use App\Extensions\Captcha\Providers\CaptchaProvider;
|
use App\Extensions\Captcha\CaptchaProvider;
|
||||||
use App\Extensions\OAuth\OAuthProvider;
|
use App\Extensions\OAuth\OAuthProvider;
|
||||||
use App\Facades\Activity;
|
use App\Facades\Activity;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@ -29,10 +29,13 @@ class Login extends BaseLogin
|
|||||||
|
|
||||||
protected OAuthProvider $oauthProvider;
|
protected OAuthProvider $oauthProvider;
|
||||||
|
|
||||||
public function boot(Google2FA $google2FA, OAuthProvider $oauthProvider): void
|
protected CaptchaProvider $captchaProvider;
|
||||||
|
|
||||||
|
public function boot(Google2FA $google2FA, OAuthProvider $oauthProvider, CaptchaProvider $captchaProvider): void
|
||||||
{
|
{
|
||||||
$this->google2FA = $google2FA;
|
$this->google2FA = $google2FA;
|
||||||
$this->oauthProvider = $oauthProvider;
|
$this->oauthProvider = $oauthProvider;
|
||||||
|
$this->captchaProvider = $captchaProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authenticate(): ?LoginResponse
|
public function authenticate(): ?LoginResponse
|
||||||
@ -145,13 +148,7 @@ class Login extends BaseLogin
|
|||||||
|
|
||||||
private function getCaptchaComponent(): ?Component
|
private function getCaptchaComponent(): ?Component
|
||||||
{
|
{
|
||||||
$captchaProvider = collect(CaptchaProvider::get())->filter(fn (CaptchaProvider $provider) => $provider->isEnabled())->first();
|
return $this->captchaProvider->getActiveSchema()?->getFormComponent();
|
||||||
|
|
||||||
if (!$captchaProvider) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $captchaProvider->getComponent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function throwFailureValidationException(): never
|
protected function throwFailureValidationException(): never
|
||||||
|
@ -2,35 +2,35 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Extensions\Captcha\CaptchaProvider;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Foundation\Application;
|
use Illuminate\Foundation\Application;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use App\Events\Auth\FailedCaptcha;
|
use App\Events\Auth\FailedCaptcha;
|
||||||
use App\Extensions\Captcha\Providers\CaptchaProvider;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||||
|
|
||||||
readonly class VerifyCaptcha
|
readonly class VerifyCaptcha
|
||||||
{
|
{
|
||||||
public function __construct(private Application $app) {}
|
public function __construct(private Application $app) {}
|
||||||
|
|
||||||
public function handle(Request $request, Closure $next): mixed
|
public function handle(Request $request, Closure $next, CaptchaProvider $captchaProvider): mixed
|
||||||
{
|
{
|
||||||
if ($this->app->isLocal()) {
|
if ($this->app->isLocal()) {
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$captchaProviders = collect(CaptchaProvider::get())->filter(fn (CaptchaProvider $provider) => $provider->isEnabled())->all();
|
$schemas = $captchaProvider->getActiveSchemas();
|
||||||
foreach ($captchaProviders as $captchaProvider) {
|
foreach ($schemas as $schema) {
|
||||||
$response = $captchaProvider->validateResponse();
|
$response = $schema->validateResponse();
|
||||||
|
|
||||||
if ($response['success'] && $captchaProvider->verifyDomain($response['hostname'] ?? '', $request->url())) {
|
if ($response['success'] && $schema->verifyDomain($response['hostname'] ?? '', $request->url())) {
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
event(new FailedCaptcha($request->ip(), $response['message'] ?? null));
|
event(new FailedCaptcha($request->ip(), $response['message'] ?? null));
|
||||||
|
|
||||||
throw new HttpException(Response::HTTP_BAD_REQUEST, "Failed to validate {$captchaProvider->getId()} captcha data.");
|
throw new HttpException(Response::HTTP_BAD_REQUEST, "Failed to validate {$schema->getId()} captcha data.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// No captcha enabled
|
// No captcha enabled
|
||||||
|
@ -10,7 +10,6 @@ use App\Checks\NodeVersionsCheck;
|
|||||||
use App\Checks\PanelVersionCheck;
|
use App\Checks\PanelVersionCheck;
|
||||||
use App\Checks\ScheduleCheck;
|
use App\Checks\ScheduleCheck;
|
||||||
use App\Checks\UsedDiskSpaceCheck;
|
use App\Checks\UsedDiskSpaceCheck;
|
||||||
use App\Extensions\Captcha\Providers\TurnstileProvider;
|
|
||||||
use App\Models;
|
use App\Models;
|
||||||
use App\Services\Helpers\SoftwareVersionService;
|
use App\Services\Helpers\SoftwareVersionService;
|
||||||
use Dedoc\Scramble\Scramble;
|
use Dedoc\Scramble\Scramble;
|
||||||
@ -92,9 +91,6 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
Scramble::registerApi('application', ['api_path' => 'api/application', 'info' => ['version' => '1.0']])->afterOpenApiGenerated($bearerTokens);
|
Scramble::registerApi('application', ['api_path' => 'api/application', 'info' => ['version' => '1.0']])->afterOpenApiGenerated($bearerTokens);
|
||||||
Scramble::registerApi('client', ['api_path' => 'api/client', 'info' => ['version' => '1.0']])->afterOpenApiGenerated($bearerTokens);
|
Scramble::registerApi('client', ['api_path' => 'api/client', 'info' => ['version' => '1.0']])->afterOpenApiGenerated($bearerTokens);
|
||||||
|
|
||||||
// Default Captcha provider
|
|
||||||
TurnstileProvider::register($app);
|
|
||||||
|
|
||||||
FilamentColor::register([
|
FilamentColor::register([
|
||||||
'danger' => Color::Red,
|
'danger' => Color::Red,
|
||||||
'gray' => Color::Zinc,
|
'gray' => Color::Zinc,
|
||||||
|
22
app/Providers/Extensions/CaptchaServiceProvider.php
Normal file
22
app/Providers/Extensions/CaptchaServiceProvider.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers\Extensions;
|
||||||
|
|
||||||
|
use App\Extensions\Captcha\CaptchaProvider;
|
||||||
|
use App\Extensions\Captcha\Schemas\Turnstile\TurnstileSchema;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class CaptchaServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
$this->app->singleton(CaptchaProvider::class, function ($app) {
|
||||||
|
$service = new CaptchaProvider();
|
||||||
|
|
||||||
|
// Default Captcha providers
|
||||||
|
$service->register(new TurnstileSchema());
|
||||||
|
|
||||||
|
return $service;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ return [
|
|||||||
App\Providers\Filament\AppPanelProvider::class,
|
App\Providers\Filament\AppPanelProvider::class,
|
||||||
App\Providers\Filament\ServerPanelProvider::class,
|
App\Providers\Filament\ServerPanelProvider::class,
|
||||||
App\Providers\Extensions\AvatarServiceProvider::class,
|
App\Providers\Extensions\AvatarServiceProvider::class,
|
||||||
|
App\Providers\Extensions\CaptchaServiceProvider::class,
|
||||||
App\Providers\Extensions\FeatureServiceProvider::class,
|
App\Providers\Extensions\FeatureServiceProvider::class,
|
||||||
App\Providers\Extensions\OAuthServiceProvider::class,
|
App\Providers\Extensions\OAuthServiceProvider::class,
|
||||||
App\Providers\RouteServiceProvider::class,
|
App\Providers\RouteServiceProvider::class,
|
||||||
|
@ -20,6 +20,6 @@ parameters:
|
|||||||
identifier: larastan.noEnvCallsOutsideOfConfig
|
identifier: larastan.noEnvCallsOutsideOfConfig
|
||||||
paths:
|
paths:
|
||||||
- app/Console/Commands/Environment/*.php
|
- app/Console/Commands/Environment/*.php
|
||||||
- app/Extensions/Captcha/Providers/*.php
|
- app/Extensions/Captcha/Schemas/*.php
|
||||||
- app/Extensions/OAuth/Schemas/*.php
|
- app/Extensions/OAuth/Schemas/*.php
|
||||||
- app/Filament/Admin/Pages/Settings.php
|
- app/Filament/Admin/Pages/Settings.php
|
||||||
|
Loading…
x
Reference in New Issue
Block a user