mirror of
https://github.com/pelican-dev/panel.git
synced 2025-09-07 13:08:36 +02:00
Refactor Providers
to be a singleton (#1327)
This commit is contained in:
parent
74bd7f9991
commit
de4cb38766
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Avatar;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
abstract class AvatarProvider
|
||||
{
|
||||
/**
|
||||
* @var array<string, static>
|
||||
*/
|
||||
protected static array $providers = [];
|
||||
|
||||
public static function getProvider(string $id): ?self
|
||||
{
|
||||
return Arr::get(static::$providers, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, static>
|
||||
*/
|
||||
public static function getAll(): array
|
||||
{
|
||||
return static::$providers;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
static::$providers[$this->getId()] = $this;
|
||||
}
|
||||
|
||||
abstract public function getId(): string;
|
||||
|
||||
abstract public function get(User $user): ?string;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return Str::title($this->getId());
|
||||
}
|
||||
}
|
14
app/Extensions/Avatar/AvatarSchemaInterface.php
Normal file
14
app/Extensions/Avatar/AvatarSchemaInterface.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Avatar;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
interface AvatarSchemaInterface
|
||||
{
|
||||
public function getId(): string;
|
||||
|
||||
public function getName(): string;
|
||||
|
||||
public function get(User $user): ?string;
|
||||
}
|
55
app/Extensions/Avatar/AvatarService.php
Normal file
55
app/Extensions/Avatar/AvatarService.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Avatar;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class AvatarService
|
||||
{
|
||||
/** @var AvatarSchemaInterface[] */
|
||||
private array $schemas = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly bool $allowUploadedAvatars,
|
||||
private readonly string $activeSchema,
|
||||
) {}
|
||||
|
||||
public function get(string $id): ?AvatarSchemaInterface
|
||||
{
|
||||
return array_get($this->schemas, $id);
|
||||
}
|
||||
|
||||
public function getActiveSchema(): ?AvatarSchemaInterface
|
||||
{
|
||||
return $this->get($this->activeSchema);
|
||||
}
|
||||
|
||||
public function getAvatarUrl(User $user): ?string
|
||||
{
|
||||
if ($this->allowUploadedAvatars) {
|
||||
$path = "avatars/$user->id.png";
|
||||
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
return Storage::url($path);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->getActiveSchema()?->get($user);
|
||||
}
|
||||
|
||||
public function register(AvatarSchemaInterface $schema): void
|
||||
{
|
||||
if (array_key_exists($schema->getId(), $this->schemas)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->schemas[$schema->getId()] = $schema;
|
||||
}
|
||||
|
||||
/** @return array<string, string> */
|
||||
public function getMappings(): array
|
||||
{
|
||||
return collect($this->schemas)->mapWithKeys(fn ($schema) => [$schema->getId() => $schema->getName()])->all();
|
||||
}
|
||||
}
|
@ -1,24 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Avatar\Providers;
|
||||
namespace App\Extensions\Avatar\Schemas;
|
||||
|
||||
use App\Extensions\Avatar\AvatarProvider;
|
||||
use App\Extensions\Avatar\AvatarSchemaInterface;
|
||||
use App\Models\User;
|
||||
|
||||
class GravatarProvider extends AvatarProvider
|
||||
class GravatarSchema implements AvatarSchemaInterface
|
||||
{
|
||||
public function getId(): string
|
||||
{
|
||||
return 'gravatar';
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Gravatar';
|
||||
}
|
||||
|
||||
public function get(User $user): string
|
||||
{
|
||||
return 'https://gravatar.com/avatar/' . md5($user->email);
|
||||
}
|
||||
|
||||
public static function register(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Avatar\Providers;
|
||||
namespace App\Extensions\Avatar\Schemas;
|
||||
|
||||
use App\Extensions\Avatar\AvatarProvider;
|
||||
use App\Extensions\Avatar\AvatarSchemaInterface;
|
||||
use App\Models\User;
|
||||
|
||||
class UiAvatarsProvider extends AvatarProvider
|
||||
class UiAvatarsSchema implements AvatarSchemaInterface
|
||||
{
|
||||
public function getId(): string
|
||||
{
|
||||
@ -22,9 +22,4 @@ class UiAvatarsProvider extends AvatarProvider
|
||||
// UI Avatars is the default of filament so just return null here
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function register(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
}
|
48
app/Extensions/Captcha/CaptchaService.php
Normal file
48
app/Extensions/Captcha/CaptchaService.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Captcha;
|
||||
|
||||
use App\Extensions\Captcha\Schemas\CaptchaSchemaInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CaptchaService
|
||||
{
|
||||
/** @var array<string, CaptchaSchemaInterface> */
|
||||
private array $schemas = [];
|
||||
|
||||
/**
|
||||
* @return CaptchaSchemaInterface[]
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return $this->schemas;
|
||||
}
|
||||
|
||||
public function get(string $id): ?CaptchaSchemaInterface
|
||||
{
|
||||
return array_get($this->schemas, $id);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -1,45 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Captcha\Providers;
|
||||
namespace App\Extensions\Captcha\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Component;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
abstract class CaptchaProvider
|
||||
abstract class BaseSchema
|
||||
{
|
||||
/**
|
||||
* @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 getComponent(): Component;
|
||||
public function getName(): string
|
||||
{
|
||||
return Str::upper($this->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
{
|
||||
return true;
|
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,11 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Components\Forms\Fields;
|
||||
namespace App\Extensions\Captcha\Schemas\Turnstile;
|
||||
|
||||
use App\Rules\ValidTurnstileCaptcha;
|
||||
use Filament\Forms\Components\Field;
|
||||
|
||||
class TurnstileCaptcha extends Field
|
||||
class Component extends Field
|
||||
{
|
||||
protected string $viewIdentifier = 'turnstile';
|
||||
|
||||
@ -19,8 +18,6 @@ class TurnstileCaptcha extends Field
|
||||
|
||||
$this->required();
|
||||
|
||||
$this->after(function (TurnstileCaptcha $component) {
|
||||
$component->rule(new ValidTurnstileCaptcha());
|
||||
});
|
||||
$this->rule(new Rule());
|
||||
}
|
||||
}
|
@ -1,16 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
namespace App\Extensions\Captcha\Schemas\Turnstile;
|
||||
|
||||
use App\Extensions\Captcha\Providers\CaptchaProvider;
|
||||
use App\Extensions\Captcha\CaptchaService;
|
||||
use Closure;
|
||||
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
|
||||
{
|
||||
$response = CaptchaProvider::get('turnstile')->validateResponse($value);
|
||||
$response = App::call(fn (CaptchaService $service) => $service->getActiveSchema()->validateResponse($value));
|
||||
|
||||
if (!$response['success']) {
|
||||
$fail($response['message'] ?? 'Unknown error occurred, please try again');
|
@ -1,26 +1,31 @@
|
||||
<?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\BaseSchema;
|
||||
use Exception;
|
||||
use Filament\Forms\Components\Component;
|
||||
use Filament\Forms\Components\Component as BaseComponent;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class TurnstileProvider extends CaptchaProvider
|
||||
class TurnstileSchema extends BaseSchema implements CaptchaSchemaInterface
|
||||
{
|
||||
public function getId(): string
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -52,20 +57,14 @@ class TurnstileProvider extends CaptchaProvider
|
||||
->label(trans('admin/setting.captcha.info_label'))
|
||||
->columnSpan(2)
|
||||
->content(new HtmlString(trans('admin/setting.captcha.info'))),
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
public function getIcon(): string
|
||||
public function getIcon(): ?string
|
||||
{
|
||||
return 'tabler-brand-cloudflare';
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string|bool>
|
||||
*/
|
@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
abstract class FeatureProvider
|
||||
{
|
||||
/**
|
||||
* @var array<string, static>
|
||||
*/
|
||||
protected static array $providers = [];
|
||||
|
||||
/**
|
||||
* @param string[] $id
|
||||
* @return self|static[]
|
||||
*/
|
||||
public static function getProviders(string|array|null $id = null): array|self
|
||||
{
|
||||
if (is_array($id)) {
|
||||
return array_intersect_key(static::$providers, array_flip($id));
|
||||
}
|
||||
|
||||
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 Feature provider with id '{$this->getId()}'");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static::$providers[$this->getId()] = $this;
|
||||
}
|
||||
|
||||
abstract public function getId(): string;
|
||||
|
||||
/**
|
||||
* A matching subset string (case-insensitive) from the console output
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
abstract public function getListeners(): array;
|
||||
|
||||
abstract public function getAction(): Action;
|
||||
}
|
15
app/Extensions/Features/FeatureSchemaInterface.php
Normal file
15
app/Extensions/Features/FeatureSchemaInterface.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
|
||||
interface FeatureSchemaInterface
|
||||
{
|
||||
/** @return string[] */
|
||||
public function getListeners(): array;
|
||||
|
||||
public function getId(): string;
|
||||
|
||||
public function getAction(): Action;
|
||||
}
|
52
app/Extensions/Features/FeatureService.php
Normal file
52
app/Extensions/Features/FeatureService.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
class FeatureService
|
||||
{
|
||||
/** @var FeatureSchemaInterface[] */
|
||||
private array $schemas = [];
|
||||
|
||||
/**
|
||||
* @return FeatureSchemaInterface[]
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return $this->schemas;
|
||||
}
|
||||
|
||||
public function get(string $id): ?FeatureSchemaInterface
|
||||
{
|
||||
return array_get($this->schemas, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $features
|
||||
* @return FeatureSchemaInterface[]
|
||||
*/
|
||||
public function getActiveSchemas(array $features): array
|
||||
{
|
||||
return collect($this->schemas)->only($features)->all();
|
||||
}
|
||||
|
||||
public function register(FeatureSchemaInterface $schema): void
|
||||
{
|
||||
if (array_key_exists($schema->getId(), $this->schemas)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->schemas[$schema->getId()] = $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $features
|
||||
* @return array<string, array<string>>
|
||||
*/
|
||||
public function getMappings(array $features): array
|
||||
{
|
||||
return collect($this->getActiveSchemas($features))
|
||||
->mapWithKeys(fn (FeatureSchemaInterface $schema) => [
|
||||
$schema->getId() => $schema->getListeners(),
|
||||
])->all();
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
namespace App\Extensions\Features\Schemas;
|
||||
|
||||
use App\Extensions\Features\FeatureSchemaInterface;
|
||||
use App\Facades\Activity;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Server;
|
||||
@ -15,18 +16,12 @@ use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class GSLToken extends FeatureProvider
|
||||
class GSLTokenSchema implements FeatureSchemaInterface
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
@ -119,9 +114,4 @@ class GSLToken extends FeatureProvider
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
namespace App\Extensions\Features\Schemas;
|
||||
|
||||
use App\Extensions\Features\FeatureSchemaInterface;
|
||||
use App\Facades\Activity;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Server;
|
||||
@ -12,15 +13,9 @@ use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
class JavaVersion extends FeatureProvider
|
||||
class JavaVersionSchema implements FeatureSchemaInterface
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
@ -92,9 +87,4 @@ class JavaVersion extends FeatureProvider
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
namespace App\Extensions\Features\Schemas;
|
||||
|
||||
use App\Extensions\Features\FeatureSchemaInterface;
|
||||
use App\Models\Server;
|
||||
use App\Repositories\Daemon\DaemonFileRepository;
|
||||
use App\Repositories\Daemon\DaemonPowerRepository;
|
||||
@ -9,17 +10,11 @@ use Exception;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class MinecraftEula extends FeatureProvider
|
||||
class MinecraftEulaSchema implements FeatureSchemaInterface
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
@ -63,9 +58,4 @@ class MinecraftEula extends FeatureProvider
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -1,19 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
namespace App\Extensions\Features\Schemas;
|
||||
|
||||
use App\Extensions\Features\FeatureSchemaInterface;
|
||||
use Filament\Actions\Action;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class PIDLimit extends FeatureProvider
|
||||
class PIDLimitSchema implements FeatureSchemaInterface
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
@ -68,9 +63,4 @@ class PIDLimit extends FeatureProvider
|
||||
->modalCancelActionLabel('Close')
|
||||
->action(fn () => null);
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -1,19 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
namespace App\Extensions\Features\Schemas;
|
||||
|
||||
use App\Extensions\Features\FeatureSchemaInterface;
|
||||
use Filament\Actions\Action;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class SteamDiskSpace extends FeatureProvider
|
||||
class SteamDiskSpaceSchema implements FeatureSchemaInterface
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
@ -56,9 +51,4 @@ class SteamDiskSpace extends FeatureProvider
|
||||
->modalCancelActionLabel('Close')
|
||||
->action(fn () => null);
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
35
app/Extensions/OAuth/OAuthSchemaInterface.php
Normal file
35
app/Extensions/OAuth/OAuthSchemaInterface.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth;
|
||||
|
||||
use Filament\Forms\Components\Component;
|
||||
use Filament\Forms\Components\Wizard\Step;
|
||||
|
||||
interface OAuthSchemaInterface
|
||||
{
|
||||
public function getId(): string;
|
||||
|
||||
public function getName(): string;
|
||||
|
||||
public function getConfigKey(): string;
|
||||
|
||||
/** @return ?class-string */
|
||||
public function getSocialiteProvider(): ?string;
|
||||
|
||||
/**
|
||||
* @return array<string, string|string[]|bool|null>
|
||||
*/
|
||||
public function getServiceConfig(): array;
|
||||
|
||||
/** @return Component[] */
|
||||
public function getSettingsForm(): array;
|
||||
|
||||
/** @return Step[] */
|
||||
public function getSetupSteps(): array;
|
||||
|
||||
public function getIcon(): ?string;
|
||||
|
||||
public function getHexColor(): ?string;
|
||||
|
||||
public function isEnabled(): bool;
|
||||
}
|
46
app/Extensions/OAuth/OAuthService.php
Normal file
46
app/Extensions/OAuth/OAuthService.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth;
|
||||
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use SocialiteProviders\Manager\SocialiteWasCalled;
|
||||
|
||||
class OAuthService
|
||||
{
|
||||
/** @var OAuthSchemaInterface[] */
|
||||
private array $schemas = [];
|
||||
|
||||
/** @return OAuthSchemaInterface[] */
|
||||
public function getAll(): array
|
||||
{
|
||||
return $this->schemas;
|
||||
}
|
||||
|
||||
public function get(string $id): ?OAuthSchemaInterface
|
||||
{
|
||||
return array_get($this->schemas, $id);
|
||||
}
|
||||
|
||||
/** @return OAuthSchemaInterface[] */
|
||||
public function getEnabled(): array
|
||||
{
|
||||
return collect($this->schemas)
|
||||
->filter(fn (OAuthSchemaInterface $schema) => $schema->isEnabled())
|
||||
->all();
|
||||
}
|
||||
|
||||
public function register(OAuthSchemaInterface $schema): void
|
||||
{
|
||||
if (array_key_exists($schema->getId(), $this->schemas)) {
|
||||
return;
|
||||
}
|
||||
|
||||
config()->set('services.' . $schema->getId(), array_merge($schema->getServiceConfig(), ['redirect' => '/auth/oauth/callback/' . $schema->getId()]));
|
||||
|
||||
if ($schema->getSocialiteProvider()) {
|
||||
Event::listen(fn (SocialiteWasCalled $event) => $event->extendSocialite($schema->getId(), $schema->getSocialiteProvider()));
|
||||
}
|
||||
|
||||
$this->schemas[$schema->getId()] = $schema;
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth\Providers;
|
||||
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
final class CommonProvider extends OAuthProvider
|
||||
{
|
||||
protected function __construct(protected Application $app, private string $id, private ?string $providerClass, private ?string $icon, private ?string $hexColor)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getProviderClass(): ?string
|
||||
{
|
||||
return $this->providerClass;
|
||||
}
|
||||
|
||||
public function getIcon(): ?string
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function getHexColor(): ?string
|
||||
{
|
||||
return $this->hexColor;
|
||||
}
|
||||
|
||||
public static function register(Application $app, string $id, ?string $providerClass = null, ?string $icon = null, ?string $hexColor = null): static
|
||||
{
|
||||
return new self($app, $id, $providerClass, $icon, $hexColor);
|
||||
}
|
||||
}
|
@ -1,25 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth\Providers;
|
||||
namespace App\Extensions\OAuth\Schemas;
|
||||
|
||||
use Filament\Forms\Components\ColorPicker;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Illuminate\Foundation\Application;
|
||||
use SocialiteProviders\Authentik\Provider;
|
||||
|
||||
final class AuthentikProvider extends OAuthProvider
|
||||
final class AuthentikSchema extends OAuthSchema
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'authentik';
|
||||
}
|
||||
|
||||
public function getProviderClass(): string
|
||||
public function getSocialiteProvider(): string
|
||||
{
|
||||
return Provider::class;
|
||||
}
|
||||
@ -66,9 +60,4 @@ final class AuthentikProvider extends OAuthProvider
|
||||
{
|
||||
return env('OAUTH_AUTHENTIK_DISPLAY_COLOR', '#fd4b2d');
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
39
app/Extensions/OAuth/Schemas/CommonSchema.php
Normal file
39
app/Extensions/OAuth/Schemas/CommonSchema.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth\Schemas;
|
||||
|
||||
final class CommonSchema extends OAuthSchema
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $id,
|
||||
private readonly ?string $name = null,
|
||||
private readonly ?string $configName = null,
|
||||
private readonly ?string $icon = null,
|
||||
private readonly ?string $hexColor = null,
|
||||
) {}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name ?? parent::getName();
|
||||
}
|
||||
|
||||
public function getConfigKey(): string
|
||||
{
|
||||
return $this->configName ?? parent::getConfigKey();
|
||||
}
|
||||
|
||||
public function getIcon(): ?string
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function getHexColor(): ?string
|
||||
{
|
||||
return $this->hexColor;
|
||||
}
|
||||
}
|
@ -1,29 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth\Providers;
|
||||
namespace App\Extensions\OAuth\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Wizard\Step;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use SocialiteProviders\Discord\Provider;
|
||||
use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction;
|
||||
|
||||
final class DiscordProvider extends OAuthProvider
|
||||
final class DiscordSchema extends OAuthSchema
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'discord';
|
||||
}
|
||||
|
||||
public function getProviderClass(): string
|
||||
public function getSocialiteProvider(): string
|
||||
{
|
||||
return Provider::class;
|
||||
}
|
||||
@ -56,9 +50,4 @@ final class DiscordProvider extends OAuthProvider
|
||||
{
|
||||
return '#5865F2';
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -1,22 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth\Providers;
|
||||
namespace App\Extensions\OAuth\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Wizard\Step;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction;
|
||||
|
||||
final class GithubProvider extends OAuthProvider
|
||||
final class GithubSchema extends OAuthSchema
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'github';
|
||||
@ -55,9 +49,4 @@ final class GithubProvider extends OAuthProvider
|
||||
{
|
||||
return '#4078c0';
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -1,22 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth\Providers;
|
||||
namespace App\Extensions\OAuth\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Wizard\Step;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction;
|
||||
|
||||
final class GitlabProvider extends OAuthProvider
|
||||
final class GitlabSchema extends OAuthSchema
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'gitlab';
|
||||
@ -68,9 +62,4 @@ final class GitlabProvider extends OAuthProvider
|
||||
{
|
||||
return '#fca326';
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -1,61 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth\Providers;
|
||||
namespace App\Extensions\OAuth\Schemas;
|
||||
|
||||
use App\Extensions\OAuth\OAuthSchemaInterface;
|
||||
use Filament\Forms\Components\Component;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Wizard\Step;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Str;
|
||||
use SocialiteProviders\Manager\SocialiteWasCalled;
|
||||
|
||||
abstract class OAuthProvider
|
||||
abstract class OAuthSchema implements OAuthSchemaInterface
|
||||
{
|
||||
/**
|
||||
* @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 OAuth provider with id '{$this->getId()}'");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
config()->set('services.' . $this->getId(), array_merge($this->getServiceConfig(), ['redirect' => '/auth/oauth/callback/' . $this->getId()]));
|
||||
|
||||
if ($this->getProviderClass()) {
|
||||
Event::listen(function (SocialiteWasCalled $event) {
|
||||
$event->extendSocialite($this->getId(), $this->getProviderClass());
|
||||
});
|
||||
}
|
||||
|
||||
static::$providers[$this->getId()] = $this;
|
||||
}
|
||||
|
||||
abstract public function getId(): string;
|
||||
|
||||
public function getProviderClass(): ?string
|
||||
public function getSocialiteProvider(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string|string[]|bool|null>
|
||||
*/
|
||||
public function getServiceConfig(): array
|
||||
{
|
||||
$id = Str::upper($this->getId());
|
||||
@ -112,6 +73,13 @@ abstract class OAuthProvider
|
||||
return Str::title($this->getId());
|
||||
}
|
||||
|
||||
public function getConfigKey(): string
|
||||
{
|
||||
$id = Str::upper($this->getId());
|
||||
|
||||
return "OAUTH_{$id}_ENABLED";
|
||||
}
|
||||
|
||||
public function getIcon(): ?string
|
||||
{
|
||||
return null;
|
@ -1,28 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\OAuth\Providers;
|
||||
namespace App\Extensions\OAuth\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Wizard\Step;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use SocialiteProviders\Steam\Provider;
|
||||
|
||||
final class SteamProvider extends OAuthProvider
|
||||
final class SteamSchema extends OAuthSchema
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'steam';
|
||||
}
|
||||
|
||||
public function getProviderClass(): string
|
||||
public function getSocialiteProvider(): string
|
||||
{
|
||||
return Provider::class;
|
||||
}
|
||||
@ -73,9 +67,4 @@ final class SteamProvider extends OAuthProvider
|
||||
{
|
||||
return '#00adee';
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Filament\Admin\Pages;
|
||||
|
||||
use App\Extensions\Avatar\AvatarProvider;
|
||||
use App\Extensions\Captcha\Providers\CaptchaProvider;
|
||||
use App\Extensions\OAuth\Providers\OAuthProvider;
|
||||
use App\Extensions\Avatar\AvatarService;
|
||||
use App\Extensions\Captcha\CaptchaService;
|
||||
use App\Extensions\OAuth\OAuthService;
|
||||
use App\Models\Backup;
|
||||
use App\Notifications\MailTested;
|
||||
use App\Traits\EnvironmentWriterTrait;
|
||||
@ -58,6 +58,12 @@ class Settings extends Page implements HasForms
|
||||
|
||||
protected static string $view = 'filament.pages.settings';
|
||||
|
||||
protected OAuthService $oauthService;
|
||||
|
||||
protected AvatarService $avatarService;
|
||||
|
||||
protected CaptchaService $captchaService;
|
||||
|
||||
/** @var array<mixed>|null */
|
||||
public ?array $data = [];
|
||||
|
||||
@ -66,6 +72,13 @@ class Settings extends Page implements HasForms
|
||||
$this->form->fill();
|
||||
}
|
||||
|
||||
public function boot(OAuthService $oauthService, AvatarService $avatarService, CaptchaService $captchaService): void
|
||||
{
|
||||
$this->oauthService = $oauthService;
|
||||
$this->avatarService = $avatarService;
|
||||
$this->captchaService = $captchaService;
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->can('view settings');
|
||||
@ -173,7 +186,7 @@ class Settings extends Page implements HasForms
|
||||
Select::make('FILAMENT_AVATAR_PROVIDER')
|
||||
->label(trans('admin/setting.general.avatar_provider'))
|
||||
->native(false)
|
||||
->options(collect(AvatarProvider::getAll())->mapWithKeys(fn ($provider) => [$provider->getId() => $provider->getName()]))
|
||||
->options($this->avatarService->getMappings())
|
||||
->selectablePlaceholder(false)
|
||||
->default(env('FILAMENT_AVATAR_PROVIDER', config('panel.filament.avatar-provider'))),
|
||||
Toggle::make('FILAMENT_UPLOADABLE_AVATARS')
|
||||
@ -264,15 +277,14 @@ class Settings extends Page implements HasForms
|
||||
{
|
||||
$formFields = [];
|
||||
|
||||
$captchaProviders = CaptchaProvider::get();
|
||||
foreach ($captchaProviders as $captchaProvider) {
|
||||
$id = Str::upper($captchaProvider->getId());
|
||||
$name = Str::title($captchaProvider->getId());
|
||||
$captchaSchemas = $this->captchaService->getAll();
|
||||
foreach ($captchaSchemas as $schema) {
|
||||
$id = Str::upper($schema->getId());
|
||||
|
||||
$formFields[] = Section::make($name)
|
||||
$formFields[] = Section::make($schema->getName())
|
||||
->columns(5)
|
||||
->icon($captchaProvider->getIcon() ?? 'tabler-shield')
|
||||
->collapsed(fn () => !env("CAPTCHA_{$id}_ENABLED", false))
|
||||
->icon($schema->getIcon() ?? 'tabler-shield')
|
||||
->collapsed(fn () => !$schema->isEnabled())
|
||||
->collapsible()
|
||||
->schema([
|
||||
Hidden::make("CAPTCHA_{$id}_ENABLED")
|
||||
@ -283,21 +295,14 @@ class Settings extends Page implements HasForms
|
||||
->visible(fn (Get $get) => $get("CAPTCHA_{$id}_ENABLED"))
|
||||
->label(trans('admin/setting.captcha.disable'))
|
||||
->color('danger')
|
||||
->action(function (Set $set) use ($id) {
|
||||
$set("CAPTCHA_{$id}_ENABLED", false);
|
||||
}),
|
||||
->action(fn (Set $set) => $set("CAPTCHA_{$id}_ENABLED", false)),
|
||||
FormAction::make("enable_captcha_$id")
|
||||
->visible(fn (Get $get) => !$get("CAPTCHA_{$id}_ENABLED"))
|
||||
->label(trans('admin/setting.captcha.enable'))
|
||||
->color('success')
|
||||
->action(function (Set $set) use ($id, $captchaProviders) {
|
||||
foreach ($captchaProviders as $captchaProvider) {
|
||||
$loopId = Str::upper($captchaProvider->getId());
|
||||
$set("CAPTCHA_{$loopId}_ENABLED", $loopId === $id);
|
||||
}
|
||||
}),
|
||||
->action(fn (Set $set) => $set("CAPTCHA_{$id}_ENABLED", true)),
|
||||
])->columnSpan(1),
|
||||
Group::make($captchaProvider->getSettingsForm())
|
||||
Group::make($schema->getSettingsForm())
|
||||
->visible(fn (Get $get) => $get("CAPTCHA_{$id}_ENABLED"))
|
||||
->columns(4)
|
||||
->columnSpan(4),
|
||||
@ -533,39 +538,37 @@ class Settings extends Page implements HasForms
|
||||
{
|
||||
$formFields = [];
|
||||
|
||||
$oauthProviders = OAuthProvider::get();
|
||||
foreach ($oauthProviders as $oauthProvider) {
|
||||
$id = Str::upper($oauthProvider->getId());
|
||||
$name = Str::title($oauthProvider->getId());
|
||||
$oauthSchemas = $this->oauthService->getAll();
|
||||
foreach ($oauthSchemas as $schema) {
|
||||
$id = Str::upper($schema->getId());
|
||||
$key = $schema->getConfigKey();
|
||||
|
||||
$formFields[] = Section::make($name)
|
||||
$formFields[] = Section::make($schema->getName())
|
||||
->columns(5)
|
||||
->icon($oauthProvider->getIcon() ?? 'tabler-brand-oauth')
|
||||
->collapsed(fn () => !env("OAUTH_{$id}_ENABLED", false))
|
||||
->icon($schema->getIcon() ?? 'tabler-brand-oauth')
|
||||
->collapsed(fn () => !env($key, false))
|
||||
->collapsible()
|
||||
->schema([
|
||||
Hidden::make("OAUTH_{$id}_ENABLED")
|
||||
Hidden::make($key)
|
||||
->live()
|
||||
->default(env("OAUTH_{$id}_ENABLED")),
|
||||
->default(env($key)),
|
||||
Actions::make([
|
||||
FormAction::make("disable_oauth_$id")
|
||||
->visible(fn (Get $get) => $get("OAUTH_{$id}_ENABLED"))
|
||||
->visible(fn (Get $get) => $get($key))
|
||||
->label(trans('admin/setting.oauth.disable'))
|
||||
->color('danger')
|
||||
->action(function (Set $set) use ($id) {
|
||||
$set("OAUTH_{$id}_ENABLED", false);
|
||||
}),
|
||||
->action(fn (Set $set) => $set($key, false)),
|
||||
FormAction::make("enable_oauth_$id")
|
||||
->visible(fn (Get $get) => !$get("OAUTH_{$id}_ENABLED"))
|
||||
->visible(fn (Get $get) => !$get($key))
|
||||
->label(trans('admin/setting.oauth.enable'))
|
||||
->color('success')
|
||||
->steps($oauthProvider->getSetupSteps())
|
||||
->modalHeading(trans('admin/setting.oauth.enable') . ' ' . $name)
|
||||
->steps($schema->getSetupSteps())
|
||||
->modalHeading(trans('admin/setting.oauth.enable') . ' ' . $schema->getName())
|
||||
->modalSubmitActionLabel(trans('admin/setting.oauth.enable'))
|
||||
->modalCancelAction(false)
|
||||
->action(function ($data, Set $set) use ($id) {
|
||||
->action(function ($data, Set $set) use ($key) {
|
||||
$data = array_merge([
|
||||
"OAUTH_{$id}_ENABLED" => 'true',
|
||||
$key => 'true',
|
||||
], $data);
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
@ -573,8 +576,8 @@ class Settings extends Page implements HasForms
|
||||
}
|
||||
}),
|
||||
])->columnSpan(1),
|
||||
Group::make($oauthProvider->getSettingsForm())
|
||||
->visible(fn (Get $get) => $get("OAUTH_{$id}_ENABLED"))
|
||||
Group::make($schema->getSettingsForm())
|
||||
->visible(fn (Get $get) => $get($key))
|
||||
->columns(4)
|
||||
->columnSpan(4),
|
||||
]);
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace App\Filament\Pages\Auth;
|
||||
|
||||
use App\Exceptions\Service\User\TwoFactorAuthenticationTokenInvalid;
|
||||
use App\Extensions\OAuth\Providers\OAuthProvider;
|
||||
use App\Extensions\OAuth\OAuthService;
|
||||
use App\Facades\Activity;
|
||||
use App\Models\ActivityLog;
|
||||
use App\Models\ApiKey;
|
||||
@ -60,9 +60,12 @@ class EditProfile extends BaseEditProfile
|
||||
|
||||
private ToggleTwoFactorService $toggleTwoFactorService;
|
||||
|
||||
public function boot(ToggleTwoFactorService $toggleTwoFactorService): void
|
||||
protected OAuthService $oauthService;
|
||||
|
||||
public function boot(ToggleTwoFactorService $toggleTwoFactorService, OAuthService $oauthService): void
|
||||
{
|
||||
$this->toggleTwoFactorService = $toggleTwoFactorService;
|
||||
$this->oauthService = $oauthService;
|
||||
}
|
||||
|
||||
public function getMaxWidth(): MaxWidth|string
|
||||
@ -72,7 +75,7 @@ class EditProfile extends BaseEditProfile
|
||||
|
||||
protected function getForms(): array
|
||||
{
|
||||
$oauthProviders = collect(OAuthProvider::get())->filter(fn (OAuthProvider $provider) => $provider->isEnabled())->all();
|
||||
$oauthSchemas = $this->oauthService->getEnabled();
|
||||
|
||||
return [
|
||||
'form' => $this->form(
|
||||
@ -155,21 +158,21 @@ class EditProfile extends BaseEditProfile
|
||||
|
||||
Tab::make(trans('profile.tabs.oauth'))
|
||||
->icon('tabler-brand-oauth')
|
||||
->visible(count($oauthProviders) > 0)
|
||||
->schema(function () use ($oauthProviders) {
|
||||
->visible(count($oauthSchemas) > 0)
|
||||
->schema(function () use ($oauthSchemas) {
|
||||
$actions = [];
|
||||
|
||||
foreach ($oauthProviders as $oauthProvider) {
|
||||
foreach ($oauthSchemas as $schema) {
|
||||
|
||||
$id = $oauthProvider->getId();
|
||||
$name = $oauthProvider->getName();
|
||||
$id = $schema->getId();
|
||||
$name = $schema->getName();
|
||||
|
||||
$unlink = array_key_exists($id, $this->getUser()->oauth ?? []);
|
||||
|
||||
$actions[] = Action::make("oauth_$id")
|
||||
->label(($unlink ? trans('profile.unlink') : trans('profile.link')) . $name)
|
||||
->icon($unlink ? 'tabler-unlink' : 'tabler-link')
|
||||
->color(Color::hex($oauthProvider->getHexColor()))
|
||||
->color(Color::hex($schema->getHexColor()))
|
||||
->action(function (UserUpdateService $updateService) use ($id, $name, $unlink) {
|
||||
if ($unlink) {
|
||||
$oauth = auth()->user()->oauth;
|
||||
|
@ -3,8 +3,8 @@
|
||||
namespace App\Filament\Pages\Auth;
|
||||
|
||||
use App\Events\Auth\ProvidedAuthenticationToken;
|
||||
use App\Extensions\Captcha\Providers\CaptchaProvider;
|
||||
use App\Extensions\OAuth\Providers\OAuthProvider;
|
||||
use App\Extensions\Captcha\CaptchaService;
|
||||
use App\Extensions\OAuth\OAuthService;
|
||||
use App\Facades\Activity;
|
||||
use App\Models\User;
|
||||
use Filament\Facades\Filament;
|
||||
@ -27,9 +27,15 @@ class Login extends BaseLogin
|
||||
|
||||
public bool $verifyTwoFactor = false;
|
||||
|
||||
public function boot(Google2FA $google2FA): void
|
||||
protected OAuthService $oauthService;
|
||||
|
||||
protected CaptchaService $captchaService;
|
||||
|
||||
public function boot(Google2FA $google2FA, OAuthService $oauthService, CaptchaService $captchaService): void
|
||||
{
|
||||
$this->google2FA = $google2FA;
|
||||
$this->oauthService = $oauthService;
|
||||
$this->captchaService = $captchaService;
|
||||
}
|
||||
|
||||
public function authenticate(): ?LoginResponse
|
||||
@ -116,8 +122,8 @@ class Login extends BaseLogin
|
||||
$this->getTwoFactorAuthenticationComponent(),
|
||||
];
|
||||
|
||||
if ($captchaProvider = $this->getCaptchaComponent()) {
|
||||
$schema = array_merge($schema, [$captchaProvider]);
|
||||
if ($captchaComponent = $this->getCaptchaComponent()) {
|
||||
$schema = array_merge($schema, [$captchaComponent]);
|
||||
}
|
||||
|
||||
return [
|
||||
@ -142,13 +148,7 @@ class Login extends BaseLogin
|
||||
|
||||
private function getCaptchaComponent(): ?Component
|
||||
{
|
||||
$captchaProvider = collect(CaptchaProvider::get())->filter(fn (CaptchaProvider $provider) => $provider->isEnabled())->first();
|
||||
|
||||
if (!$captchaProvider) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $captchaProvider->getComponent();
|
||||
return $this->captchaService->getActiveSchema()?->getFormComponent();
|
||||
}
|
||||
|
||||
protected function throwFailureValidationException(): never
|
||||
@ -174,16 +174,16 @@ class Login extends BaseLogin
|
||||
{
|
||||
$actions = [];
|
||||
|
||||
$oauthProviders = collect(OAuthProvider::get())->filter(fn (OAuthProvider $provider) => $provider->isEnabled())->all();
|
||||
$oauthSchemas = $this->oauthService->getEnabled();
|
||||
|
||||
foreach ($oauthProviders as $oauthProvider) {
|
||||
foreach ($oauthSchemas as $schema) {
|
||||
|
||||
$id = $oauthProvider->getId();
|
||||
$id = $schema->getId();
|
||||
|
||||
$actions[] = Action::make("oauth_$id")
|
||||
->label($oauthProvider->getName())
|
||||
->icon($oauthProvider->getIcon())
|
||||
->color(Color::hex($oauthProvider->getHexColor()))
|
||||
->label($schema->getName())
|
||||
->icon($schema->getIcon())
|
||||
->color(Color::hex($schema->getHexColor()))
|
||||
->url(route('auth.oauth.redirect', ['driver' => $id], false));
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ namespace App\Filament\Server\Pages;
|
||||
use App\Enums\ConsoleWidgetPosition;
|
||||
use App\Enums\ContainerStatus;
|
||||
use App\Exceptions\Http\Server\ServerStateConflictException;
|
||||
use App\Extensions\Features\FeatureProvider;
|
||||
use App\Extensions\Features\FeatureService;
|
||||
use App\Filament\Server\Widgets\ServerConsole;
|
||||
use App\Filament\Server\Widgets\ServerCpuChart;
|
||||
use App\Filament\Server\Widgets\ServerMemoryChart;
|
||||
@ -38,6 +38,8 @@ class Console extends Page
|
||||
|
||||
public ContainerStatus $status = ContainerStatus::Offline;
|
||||
|
||||
protected FeatureService $featureService;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
/** @var Server $server */
|
||||
@ -54,12 +56,12 @@ class Console extends Page
|
||||
}
|
||||
}
|
||||
|
||||
public function boot(): void
|
||||
public function boot(FeatureService $featureService): void
|
||||
{
|
||||
$this->featureService = $featureService;
|
||||
/** @var Server $server */
|
||||
$server = Filament::getTenant();
|
||||
/** @var FeatureProvider $feature */
|
||||
foreach ($server->egg->features() as $feature) {
|
||||
foreach ($featureService->getActiveSchemas($server->egg->features) as $feature) {
|
||||
$this->cacheAction($feature->getAction());
|
||||
}
|
||||
}
|
||||
@ -70,8 +72,8 @@ class Console extends Page
|
||||
$data = json_decode($data);
|
||||
$feature = data_get($data, 'key');
|
||||
|
||||
$feature = FeatureProvider::getProviders($feature);
|
||||
if ($this->getMountedAction()) {
|
||||
$feature = $this->featureService->get($feature);
|
||||
if (!$feature || $this->getMountedAction()) {
|
||||
return;
|
||||
}
|
||||
$this->mountAction($feature->getId());
|
||||
|
@ -2,23 +2,24 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Extensions\OAuth\Providers\OAuthProvider;
|
||||
use App\Extensions\OAuth\OAuthService;
|
||||
use App\Filament\Pages\Auth\EditProfile;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Auth\AuthManager;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Services\Users\UserUpdateService;
|
||||
use Exception;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Auth\AuthManager;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
|
||||
class OAuthController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AuthManager $auth,
|
||||
private readonly UserUpdateService $updateService
|
||||
private readonly UserUpdateService $updateService,
|
||||
private readonly OAuthService $oauthService
|
||||
) {}
|
||||
|
||||
/**
|
||||
@ -27,7 +28,7 @@ class OAuthController extends Controller
|
||||
public function redirect(string $driver): RedirectResponse
|
||||
{
|
||||
// Driver is disabled - redirect to normal login
|
||||
if (!OAuthProvider::get($driver)->isEnabled()) {
|
||||
if (!$this->oauthService->get($driver)->isEnabled()) {
|
||||
return redirect()->route('auth.login');
|
||||
}
|
||||
|
||||
@ -40,7 +41,7 @@ class OAuthController extends Controller
|
||||
public function callback(Request $request, string $driver): RedirectResponse
|
||||
{
|
||||
// Driver is disabled - redirect to normal login
|
||||
if (!OAuthProvider::get($driver)->isEnabled()) {
|
||||
if (!$this->oauthService->get($driver)?->isEnabled()) {
|
||||
return redirect()->route('auth.login');
|
||||
}
|
||||
|
||||
|
@ -2,35 +2,35 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Extensions\Captcha\CaptchaService;
|
||||
use Closure;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use App\Events\Auth\FailedCaptcha;
|
||||
use App\Extensions\Captcha\Providers\CaptchaProvider;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
readonly class VerifyCaptcha
|
||||
{
|
||||
public function __construct(private Application $app) {}
|
||||
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
public function handle(Request $request, Closure $next, CaptchaService $captchaService): mixed
|
||||
{
|
||||
if ($this->app->isLocal()) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$captchaProviders = collect(CaptchaProvider::get())->filter(fn (CaptchaProvider $provider) => $provider->isEnabled())->all();
|
||||
foreach ($captchaProviders as $captchaProvider) {
|
||||
$response = $captchaProvider->validateResponse();
|
||||
$schemas = $captchaService->getActiveSchemas();
|
||||
foreach ($schemas as $schema) {
|
||||
$response = $schema->validateResponse();
|
||||
|
||||
if ($response['success'] && $captchaProvider->verifyDomain($response['hostname'] ?? '', $request->url())) {
|
||||
if ($response['success'] && $schema->verifyDomain($response['hostname'] ?? '', $request->url())) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -5,13 +5,12 @@ namespace App\Models;
|
||||
use App\Contracts\Validatable;
|
||||
use App\Exceptions\Service\Egg\HasChildrenException;
|
||||
use App\Exceptions\Service\HasActiveServersException;
|
||||
use App\Extensions\Features\FeatureProvider;
|
||||
use App\Traits\HasValidation;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
@ -161,12 +160,6 @@ class Egg extends Model implements Validatable
|
||||
});
|
||||
}
|
||||
|
||||
/** @return array<FeatureProvider> */
|
||||
public function features(): array
|
||||
{
|
||||
return FeatureProvider::getProviders($this->features);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the install script for the egg; if egg is copying from another
|
||||
* it will return the copied script.
|
||||
|
@ -4,9 +4,8 @@ namespace App\Models;
|
||||
|
||||
use App\Contracts\Validatable;
|
||||
use App\Exceptions\DisplayException;
|
||||
use App\Extensions\Avatar\AvatarProvider;
|
||||
use App\Extensions\Avatar\AvatarService;
|
||||
use App\Rules\Username;
|
||||
use App\Facades\Activity;
|
||||
use App\Traits\HasValidation;
|
||||
use DateTimeZone;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
@ -18,6 +17,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules\In;
|
||||
use Illuminate\Auth\Authenticatable;
|
||||
@ -32,7 +32,6 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use ResourceBundle;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
|
||||
@ -397,17 +396,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
|
||||
|
||||
public function getFilamentAvatarUrl(): ?string
|
||||
{
|
||||
if (config('panel.filament.uploadable-avatars')) {
|
||||
$path = "avatars/$this->id.png";
|
||||
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
return Storage::url($path);
|
||||
}
|
||||
}
|
||||
|
||||
$provider = AvatarProvider::getProvider(config('panel.filament.avatar-provider'));
|
||||
|
||||
return $provider?->get($this);
|
||||
return App::call(fn (AvatarService $service) => $service->getAvatarUrl($this));
|
||||
}
|
||||
|
||||
public function canTarget(Model $model): bool
|
||||
|
@ -10,21 +10,7 @@ use App\Checks\NodeVersionsCheck;
|
||||
use App\Checks\PanelVersionCheck;
|
||||
use App\Checks\ScheduleCheck;
|
||||
use App\Checks\UsedDiskSpaceCheck;
|
||||
use App\Extensions\Avatar\Providers\GravatarProvider;
|
||||
use App\Extensions\Avatar\Providers\UiAvatarsProvider;
|
||||
use App\Extensions\OAuth\Providers\GitlabProvider;
|
||||
use App\Models;
|
||||
use App\Extensions\Captcha\Providers\TurnstileProvider;
|
||||
use App\Extensions\Features\GSLToken;
|
||||
use App\Extensions\Features\JavaVersion;
|
||||
use App\Extensions\Features\MinecraftEula;
|
||||
use App\Extensions\Features\PIDLimit;
|
||||
use App\Extensions\Features\SteamDiskSpace;
|
||||
use App\Extensions\OAuth\Providers\AuthentikProvider;
|
||||
use App\Extensions\OAuth\Providers\CommonProvider;
|
||||
use App\Extensions\OAuth\Providers\DiscordProvider;
|
||||
use App\Extensions\OAuth\Providers\GithubProvider;
|
||||
use App\Extensions\OAuth\Providers\SteamProvider;
|
||||
use App\Services\Helpers\SoftwareVersionService;
|
||||
use Dedoc\Scramble\Scramble;
|
||||
use Dedoc\Scramble\Support\Generator\OpenApi;
|
||||
@ -105,35 +91,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
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);
|
||||
|
||||
// Default OAuth providers included with Socialite
|
||||
CommonProvider::register($app, 'facebook', null, 'tabler-brand-facebook-f', '#1877f2');
|
||||
CommonProvider::register($app, 'x', null, 'tabler-brand-x-f', '#1da1f2');
|
||||
CommonProvider::register($app, 'linkedin', null, 'tabler-brand-linkedin-f', '#0a66c2');
|
||||
CommonProvider::register($app, 'google', null, 'tabler-brand-google-f', '#4285f4');
|
||||
GithubProvider::register($app);
|
||||
GitlabProvider::register($app);
|
||||
CommonProvider::register($app, 'bitbucket', null, 'tabler-brand-bitbucket-f', '#205081');
|
||||
CommonProvider::register($app, 'slack', null, 'tabler-brand-slack', '#6ecadc');
|
||||
|
||||
// Additional OAuth providers from socialiteproviders.com
|
||||
AuthentikProvider::register($app);
|
||||
DiscordProvider::register($app);
|
||||
SteamProvider::register($app);
|
||||
|
||||
// Default Captcha provider
|
||||
TurnstileProvider::register($app);
|
||||
|
||||
// Default Avatar providers
|
||||
GravatarProvider::register();
|
||||
UiAvatarsProvider::register();
|
||||
|
||||
// Default Feature providers
|
||||
GSLToken::register($app);
|
||||
JavaVersion::register($app);
|
||||
MinecraftEula::register($app);
|
||||
PIDLimit::register($app);
|
||||
SteamDiskSpace::register($app);
|
||||
|
||||
FilamentColor::register([
|
||||
'danger' => Color::Red,
|
||||
'gray' => Color::Zinc,
|
||||
|
24
app/Providers/Extensions/AvatarServiceProvider.php
Normal file
24
app/Providers/Extensions/AvatarServiceProvider.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers\Extensions;
|
||||
|
||||
use App\Extensions\Avatar\AvatarService;
|
||||
use App\Extensions\Avatar\Schemas\GravatarSchema;
|
||||
use App\Extensions\Avatar\Schemas\UiAvatarsSchema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AvatarServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->singleton(AvatarService::class, function ($app) {
|
||||
$service = new AvatarService(config('panel.filament.uploadable-avatars', false), config('panel.filament.avatar-provider', 'gravatar'));
|
||||
|
||||
// Default Avatar providers
|
||||
$service->register(new GravatarSchema());
|
||||
$service->register(new UiAvatarsSchema());
|
||||
|
||||
return $service;
|
||||
});
|
||||
}
|
||||
}
|
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\CaptchaService;
|
||||
use App\Extensions\Captcha\Schemas\Turnstile\TurnstileSchema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class CaptchaServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->singleton(CaptchaService::class, function ($app) {
|
||||
$service = new CaptchaService();
|
||||
|
||||
// Default Captcha providers
|
||||
$service->register(new TurnstileSchema());
|
||||
|
||||
return $service;
|
||||
});
|
||||
}
|
||||
}
|
30
app/Providers/Extensions/FeatureServiceProvider.php
Normal file
30
app/Providers/Extensions/FeatureServiceProvider.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers\Extensions;
|
||||
|
||||
use App\Extensions\Features\FeatureService;
|
||||
use App\Extensions\Features\Schemas\GSLTokenSchema;
|
||||
use App\Extensions\Features\Schemas\JavaVersionSchema;
|
||||
use App\Extensions\Features\Schemas\MinecraftEulaSchema;
|
||||
use App\Extensions\Features\Schemas\PIDLimitSchema;
|
||||
use App\Extensions\Features\Schemas\SteamDiskSpaceSchema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class FeatureServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->singleton(FeatureService::class, function ($app) {
|
||||
$provider = new FeatureService();
|
||||
|
||||
// Default Feature providers
|
||||
$provider->register(new GSLTokenSchema());
|
||||
$provider->register(new JavaVersionSchema());
|
||||
$provider->register(new MinecraftEulaSchema());
|
||||
$provider->register(new PIDLimitSchema());
|
||||
$provider->register(new SteamDiskSpaceSchema());
|
||||
|
||||
return $provider;
|
||||
});
|
||||
}
|
||||
}
|
39
app/Providers/Extensions/OAuthServiceProvider.php
Normal file
39
app/Providers/Extensions/OAuthServiceProvider.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers\Extensions;
|
||||
|
||||
use App\Extensions\OAuth\OAuthService;
|
||||
use App\Extensions\OAuth\Schemas\AuthentikSchema;
|
||||
use App\Extensions\OAuth\Schemas\CommonSchema;
|
||||
use App\Extensions\OAuth\Schemas\DiscordSchema;
|
||||
use App\Extensions\OAuth\Schemas\GithubSchema;
|
||||
use App\Extensions\OAuth\Schemas\GitlabSchema;
|
||||
use App\Extensions\OAuth\Schemas\SteamSchema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class OAuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->singleton(OAuthService::class, function ($app) {
|
||||
$service = new OAuthService();
|
||||
|
||||
// Default OAuth providers included with Socialite
|
||||
$service->register(new CommonSchema('facebook', icon: 'tabler-brand-facebook-f', hexColor: '#1877f2'));
|
||||
$service->register(new CommonSchema('x', icon: 'tabler-brand-x-f', hexColor: '#1da1f2'));
|
||||
$service->register(new CommonSchema('linkedin', icon: 'tabler-brand-linkedin-f', hexColor: '#0a66c2'));
|
||||
$service->register(new CommonSchema('google', icon: 'tabler-brand-google-f', hexColor: '#4285f4'));
|
||||
$service->register(new GithubSchema());
|
||||
$service->register(new GitlabSchema());
|
||||
$service->register(new CommonSchema('bitbucket', icon: 'tabler-brand-bitbucket-f', hexColor: '#205081'));
|
||||
$service->register(new CommonSchema('slack', icon: 'tabler-brand-slack', hexColor: '#6ecadc'));
|
||||
|
||||
// Additional OAuth providers from socialiteproviders.com
|
||||
$service->register(new AuthentikSchema());
|
||||
$service->register(new DiscordSchema());
|
||||
$service->register(new SteamSchema());
|
||||
|
||||
return $service;
|
||||
});
|
||||
}
|
||||
}
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace App\Services\Servers;
|
||||
|
||||
use App\Extensions\Features\FeatureService;
|
||||
use App\Models\Egg;
|
||||
use App\Models\Mount;
|
||||
use App\Models\Server;
|
||||
|
||||
class ServerConfigurationStructureService
|
||||
{
|
||||
public function __construct(private EnvironmentService $environment) {}
|
||||
public function __construct(private EnvironmentService $environment, private FeatureService $featureService) {}
|
||||
|
||||
/**
|
||||
* Return a configuration array for a specific server when passed a server model.
|
||||
@ -58,7 +60,7 @@ class ServerConfigurationStructureService
|
||||
* default: array{ip: string, port: int},
|
||||
* mappings: array<string, array<int>>,
|
||||
* },
|
||||
* egg: array{id: string, file_denylist: string[]},
|
||||
* egg: array{id: string, file_denylist: string[], features: string[][]},
|
||||
* labels?: string[],
|
||||
* mounts: array{source: string, target: string, read_only: bool},
|
||||
* }
|
||||
@ -101,9 +103,7 @@ class ServerConfigurationStructureService
|
||||
'egg' => [
|
||||
'id' => $server->egg->uuid,
|
||||
'file_denylist' => $server->egg->inherit_file_denylist,
|
||||
'features' => collect($server->egg->features())->mapWithKeys(fn ($feature) => [
|
||||
$feature->getId() => $feature->getListeners(),
|
||||
])->all(),
|
||||
'features' => $this->featureService->getMappings($server->egg->features),
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -8,6 +8,10 @@ return [
|
||||
App\Providers\Filament\AdminPanelProvider::class,
|
||||
App\Providers\Filament\AppPanelProvider::class,
|
||||
App\Providers\Filament\ServerPanelProvider::class,
|
||||
App\Providers\Extensions\AvatarServiceProvider::class,
|
||||
App\Providers\Extensions\CaptchaServiceProvider::class,
|
||||
App\Providers\Extensions\FeatureServiceProvider::class,
|
||||
App\Providers\Extensions\OAuthServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
SocialiteProviders\Manager\ServiceProvider::class,
|
||||
];
|
||||
|
@ -20,6 +20,6 @@ parameters:
|
||||
identifier: larastan.noEnvCallsOutsideOfConfig
|
||||
paths:
|
||||
- app/Console/Commands/Environment/*.php
|
||||
- app/Extensions/Captcha/Providers/*.php
|
||||
- app/Extensions/OAuth/Providers/*.php
|
||||
- app/Extensions/Captcha/Schemas/*.php
|
||||
- app/Extensions/OAuth/Schemas/*.php
|
||||
- app/Filament/Admin/Pages/Settings.php
|
||||
|
Loading…
x
Reference in New Issue
Block a user