From c4559a6f0326b66c49704ecad3f6f5eed02562eb Mon Sep 17 00:00:00 2001
From: Alexe Vlad
Date: Thu, 21 Sep 2023 06:44:02 +0000
Subject: [PATCH 01/13] fix: solved routing handler for admin settings
---
.../components/admin/settings/GeneralSettings.tsx | 13 +++++++++++--
.../components/admin/settings/SettingsContainer.tsx | 10 +++++-----
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/resources/scripts/components/admin/settings/GeneralSettings.tsx b/resources/scripts/components/admin/settings/GeneralSettings.tsx
index eb4ece2c8c..8104c5a689 100644
--- a/resources/scripts/components/admin/settings/GeneralSettings.tsx
+++ b/resources/scripts/components/admin/settings/GeneralSettings.tsx
@@ -3,14 +3,24 @@ import tw from 'twin.macro';
import AdminBox from '@/components/admin/AdminBox';
import Field, { FieldRow } from '@/components/elements/Field';
+import { useStoreState } from 'easy-peasy';
+import { ApplicationStore } from '@/state';
export default () => {
+ const { name: appName } = useStoreState((state: ApplicationStore) => state.settings.data!);
+
const submit = () => {
//
};
return (
-
+
diff --git a/resources/scripts/components/admin/settings/SecuritySettings.tsx b/resources/scripts/components/admin/settings/SecuritySettings.tsx
new file mode 100644
index 0000000000..0f6831bc6e
--- /dev/null
+++ b/resources/scripts/components/admin/settings/SecuritySettings.tsx
@@ -0,0 +1,79 @@
+import { Form, Formik } from 'formik';
+import tw from 'twin.macro';
+
+import AdminBox from '@/components/admin/AdminBox';
+import Field, { FieldRow } from '@/components/elements/Field';
+import { useStoreState } from 'easy-peasy';
+import { ApplicationStore } from '@/state';
+import SelectField from '@/components/elements/SelectField';
+
+export default () => {
+ const { recaptcha } = useStoreState((state: ApplicationStore) => state.settings.data!);
+ const { enabled: recaptchaStatus, siteKey } = recaptcha;
+
+ const submit = () => {
+ //
+ };
+
+ return (
+
+
+
+ );
+};
diff --git a/resources/scripts/components/admin/settings/SettingsContainer.tsx b/resources/scripts/components/admin/settings/SettingsContainer.tsx
index 6b10ab7de8..bce6cf13b9 100644
--- a/resources/scripts/components/admin/settings/SettingsContainer.tsx
+++ b/resources/scripts/components/admin/settings/SettingsContainer.tsx
@@ -7,6 +7,7 @@ import MailSettings from '@/components/admin/settings/MailSettings';
import FlashMessageRender from '@/components/FlashMessageRender';
import { SubNavigation, SubNavigationLink } from '@/components/admin/SubNavigation';
import GeneralSettings from '@/components/admin/settings/GeneralSettings';
+import SecuritySettings from './SecuritySettings';
export default () => {
return (
@@ -43,7 +44,7 @@ export default () => {
} />
} />
- Security
} />
+ } />
Features} />
Advanced} />
From 240e1e314212116169545efaca6c9bb8dc5d17f8 Mon Sep 17 00:00:00 2001
From: Alexe Vlad
Date: Thu, 21 Sep 2023 09:14:01 +0000
Subject: [PATCH 03/13] feat(settings-ui): added controller for settings
---
.../Api/Application/SettingsController.php | 49 +++++++++++++++++++
.../admin/settings/SettingsContainer.tsx | 2 +-
routes/api-application.php | 4 +-
3 files changed, 53 insertions(+), 2 deletions(-)
create mode 100644 app/Http/Controllers/Api/Application/SettingsController.php
diff --git a/app/Http/Controllers/Api/Application/SettingsController.php b/app/Http/Controllers/Api/Application/SettingsController.php
new file mode 100644
index 0000000000..f5b49607e8
--- /dev/null
+++ b/app/Http/Controllers/Api/Application/SettingsController.php
@@ -0,0 +1,49 @@
+ [
+ 'app_name' => config('app.name'),
+ 'languages' => $this->getAvailableLanguages(true),
+ ],
+ 'mail' => [
+ 'host' => config('mail.mailers.smtp.host'),
+ 'port' => config('mail.mailers.smtp.port'),
+ 'encryption' => config('mail.mailers.smtp.encryption'),
+ 'username' => config('mail.mailers.smtp.username'),
+ 'password' => config('mail.mailers.smtp.password'),
+ 'from_address' => config('mail.from.address'),
+ 'from_name' => config('mail.from.name')
+ ],
+ 'security' => [
+ 'recaptcha' => [
+ 'enabled' => config('recaptcha.enabled'),
+ 'site_key' => config('recaptcha.website_key'),
+ 'secret_key' => config('recaptcha.secret_key'),
+ ],
+ '2fa_enabled' => config('pterodactyl.auth.2fa_required'),
+ ],
+ ]);
+ }
+}
diff --git a/resources/scripts/components/admin/settings/SettingsContainer.tsx b/resources/scripts/components/admin/settings/SettingsContainer.tsx
index bce6cf13b9..34b4ca55b0 100644
--- a/resources/scripts/components/admin/settings/SettingsContainer.tsx
+++ b/resources/scripts/components/admin/settings/SettingsContainer.tsx
@@ -7,7 +7,7 @@ import MailSettings from '@/components/admin/settings/MailSettings';
import FlashMessageRender from '@/components/FlashMessageRender';
import { SubNavigation, SubNavigationLink } from '@/components/admin/SubNavigation';
import GeneralSettings from '@/components/admin/settings/GeneralSettings';
-import SecuritySettings from './SecuritySettings';
+import SecuritySettings from '@/components/admin/settings/SecuritySettings';
export default () => {
return (
diff --git a/routes/api-application.php b/routes/api-application.php
index 717739dda7..96f785b7c9 100644
--- a/routes/api-application.php
+++ b/routes/api-application.php
@@ -4,7 +4,9 @@
use Pterodactyl\Http\Controllers\Api\Application;
Route::get('/version', [Application\VersionController::class, '__invoke']);
-
+Route::group(['prefix' => '/settings'], function () {
+ Route::get('/', [Application\SettingsController::class, '__invoke']);
+});
/*
|--------------------------------------------------------------------------
| Database Controller Routes
From f71a62668c4a5cf6241b6559028b0cd27f1758da Mon Sep 17 00:00:00 2001
From: Alexe Vlad
Date: Thu, 21 Sep 2023 19:13:39 +0000
Subject: [PATCH 04/13] fix: remove Google Analytics
---
.../components/admin/settings/GeneralSettings.tsx | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/resources/scripts/components/admin/settings/GeneralSettings.tsx b/resources/scripts/components/admin/settings/GeneralSettings.tsx
index 4c419d7633..c030f710bf 100644
--- a/resources/scripts/components/admin/settings/GeneralSettings.tsx
+++ b/resources/scripts/components/admin/settings/GeneralSettings.tsx
@@ -30,17 +30,6 @@ export default () => {
-
-
-
-
-
Date: Fri, 22 Sep 2023 07:02:14 +0000
Subject: [PATCH 05/13] ui(admin): added advanced settings, settings
service/transformer & fixed styling
---
.../Api/Application/SettingsController.php | 34 ++------
app/Models/Setting.php | 5 ++
app/Services/Helpers/SettingsService.php | 40 +++++++++
.../Api/Application/SettingsTransformer.php | 47 +++++++++++
.../admin/settings/AdvancedSettings.tsx | 82 +++++++++++++++++++
.../admin/settings/SettingsContainer.tsx | 3 +-
.../scripts/components/elements/Input.tsx | 2 +-
7 files changed, 182 insertions(+), 31 deletions(-)
create mode 100644 app/Services/Helpers/SettingsService.php
create mode 100644 app/Transformers/Api/Application/SettingsTransformer.php
create mode 100644 resources/scripts/components/admin/settings/AdvancedSettings.tsx
diff --git a/app/Http/Controllers/Api/Application/SettingsController.php b/app/Http/Controllers/Api/Application/SettingsController.php
index f5b49607e8..29dcdcd4e6 100644
--- a/app/Http/Controllers/Api/Application/SettingsController.php
+++ b/app/Http/Controllers/Api/Application/SettingsController.php
@@ -2,16 +2,15 @@
namespace Pterodactyl\Http\Controllers\Api\Application;
-use Illuminate\Http\JsonResponse;
-use Pterodactyl\Traits\Helpers\AvailableLanguages;
+use Pterodactyl\Services\Helpers\SettingsService;
+use Pterodactyl\Transformers\Api\Application\SettingsTransformer;
class SettingsController extends ApplicationApiController
{
- use AvailableLanguages;
/**
* VersionController constructor.
*/
- public function __construct()
+ public function __construct(private SettingsService $settingsService)
{
parent::__construct();
}
@@ -19,31 +18,8 @@ public function __construct()
/**
* Returns version information.
*/
- public function __invoke(): JsonResponse
+ public function __invoke(): array
{
- // TODO: Make transformer, and add more information.
- return new JsonResponse([
- 'general' => [
- 'app_name' => config('app.name'),
- 'languages' => $this->getAvailableLanguages(true),
- ],
- 'mail' => [
- 'host' => config('mail.mailers.smtp.host'),
- 'port' => config('mail.mailers.smtp.port'),
- 'encryption' => config('mail.mailers.smtp.encryption'),
- 'username' => config('mail.mailers.smtp.username'),
- 'password' => config('mail.mailers.smtp.password'),
- 'from_address' => config('mail.from.address'),
- 'from_name' => config('mail.from.name')
- ],
- 'security' => [
- 'recaptcha' => [
- 'enabled' => config('recaptcha.enabled'),
- 'site_key' => config('recaptcha.website_key'),
- 'secret_key' => config('recaptcha.secret_key'),
- ],
- '2fa_enabled' => config('pterodactyl.auth.2fa_required'),
- ],
- ]);
+ return $this->fractal->item($this->settingsService->getCurrentSettings())->transformWith(SettingsTransformer::class)->toArray();
}
}
diff --git a/app/Models/Setting.php b/app/Models/Setting.php
index b8812bc665..56e516c53e 100644
--- a/app/Models/Setting.php
+++ b/app/Models/Setting.php
@@ -11,6 +11,11 @@
*/
class Setting extends Model
{
+ /**
+ * The resource name for this model when it is transformed into an
+ * API representation using fractal.
+ */
+ public const RESOURCE_NAME = 'settings';
/**
* The table associated with the model.
*/
diff --git a/app/Services/Helpers/SettingsService.php b/app/Services/Helpers/SettingsService.php
new file mode 100644
index 0000000000..3103aaa761
--- /dev/null
+++ b/app/Services/Helpers/SettingsService.php
@@ -0,0 +1,40 @@
+ [
+ 'name' => config('app.name'),
+ 'languages' => $this->getAvailableLanguages(true),
+ ],
+ 'mail' => [
+ 'host' => config('mail.mailers.smtp.host'),
+ 'port' => config('mail.mailers.smtp.port'),
+ 'encryption' => config('mail.mailers.smtp.encryption'),
+ 'username' => config('mail.mailers.smtp.username'),
+ 'password' => config('mail.mailers.smtp.password'),
+ 'from_address' => config('mail.from.address'),
+ 'from_name' => config('mail.from.name')
+ ],
+ 'security' => [
+ 'recaptcha' => [
+ 'enabled' => config('recaptcha.enabled'),
+ 'site_key' => config('recaptcha.website_key'),
+ 'secret_key' => config('recaptcha.secret_key'),
+ ],
+ '2fa_enabled' => config('pterodactyl.auth.2fa_required'),
+ ],
+ );
+ }
+}
diff --git a/app/Transformers/Api/Application/SettingsTransformer.php b/app/Transformers/Api/Application/SettingsTransformer.php
new file mode 100644
index 0000000000..dda5399a89
--- /dev/null
+++ b/app/Transformers/Api/Application/SettingsTransformer.php
@@ -0,0 +1,47 @@
+ [
+ 'name' => $model['general']['name'],
+ 'languages' => $model['general']['languages'],
+ ],
+ 'mail' => [
+ 'host' => $model['mail']['host'],
+ 'port' => $model['mail']['port'],
+ 'from_address' => $model['mail']['from_address'],
+ 'from_name' => $model['mail']['from_name'],
+ 'encryption' => $model['mail']['encryption'],
+ 'username' => $model['mail']['username'],
+ 'password' => $model['mail']['password'],
+ ],
+ 'security' => [
+ 'recaptcha' => [
+ 'enabled' => $model['security']['recaptcha']['enabled'],
+ 'site_key' => $model['security']['recaptcha']['site_key'],
+ 'secret_key' => $model['security']['recaptcha']['secret_key'],
+ ],
+ '2fa_enabled' => $model['security']['2fa_enabled'],
+ ],
+ ];
+ }
+}
diff --git a/resources/scripts/components/admin/settings/AdvancedSettings.tsx b/resources/scripts/components/admin/settings/AdvancedSettings.tsx
new file mode 100644
index 0000000000..002ff1de4d
--- /dev/null
+++ b/resources/scripts/components/admin/settings/AdvancedSettings.tsx
@@ -0,0 +1,82 @@
+import { Form, Formik } from 'formik';
+import tw from 'twin.macro';
+
+import AdminBox from '@/components/admin/AdminBox';
+import Field, { FieldRow } from '@/components/elements/Field';
+import SelectField from '@/components/elements/SelectField';
+
+export default () => {
+ const submit = () => {
+ //
+ };
+
+ return (
+
+
+
+ );
+};
diff --git a/resources/scripts/components/admin/settings/SettingsContainer.tsx b/resources/scripts/components/admin/settings/SettingsContainer.tsx
index 34b4ca55b0..8bf6de1fcb 100644
--- a/resources/scripts/components/admin/settings/SettingsContainer.tsx
+++ b/resources/scripts/components/admin/settings/SettingsContainer.tsx
@@ -8,6 +8,7 @@ import FlashMessageRender from '@/components/FlashMessageRender';
import { SubNavigation, SubNavigationLink } from '@/components/admin/SubNavigation';
import GeneralSettings from '@/components/admin/settings/GeneralSettings';
import SecuritySettings from '@/components/admin/settings/SecuritySettings';
+import AdvancedSettings from './AdvancedSettings';
export default () => {
return (
@@ -46,7 +47,7 @@ export default () => {
} />
} />
Features} />
- Advanced} />
+ } />
);
diff --git a/resources/scripts/components/elements/Input.tsx b/resources/scripts/components/elements/Input.tsx
index 89e6bb88e0..8537e96c5b 100644
--- a/resources/scripts/components/elements/Input.tsx
+++ b/resources/scripts/components/elements/Input.tsx
@@ -45,7 +45,7 @@ const inputStyle = css`
& + .input-help {
${tw`mt-1 text-xs`};
- ${props => (props.hasError ? tw`text-red-200` : tw`text-neutral-200`)};
+ ${props => (props.hasError ? tw`text-red-200` : tw`text-neutral-400`)};
}
&:required,
From 2e2007e674829b0f95296717b646000dedb2d159 Mon Sep 17 00:00:00 2001
From: Alexe Vlad
Date: Fri, 22 Sep 2023 14:53:27 +0000
Subject: [PATCH 06/13] ui(admin): glueing backend and frontend
---
resources/scripts/api/admin/settings.ts | 48 +++++++++++++++++++
.../api/definitions/admin/transformers.ts | 26 ++++++++++
.../admin/settings/GeneralSettings.tsx | 8 +++-
.../admin/settings/MailSettings.tsx | 7 ++-
.../admin/settings/SecuritySettings.tsx | 7 ++-
.../admin/settings/SettingsContainer.tsx | 17 ++++++-
6 files changed, 108 insertions(+), 5 deletions(-)
create mode 100644 resources/scripts/api/admin/settings.ts
diff --git a/resources/scripts/api/admin/settings.ts b/resources/scripts/api/admin/settings.ts
new file mode 100644
index 0000000000..c13c831435
--- /dev/null
+++ b/resources/scripts/api/admin/settings.ts
@@ -0,0 +1,48 @@
+import { Model } from '@/api/admin/index';
+import http from '@/api/http';
+import Transformers from '../definitions/admin/transformers';
+import useSWR from 'swr';
+
+export interface Settings extends Model {
+ general: GeneralSettings;
+ mail: MailSettings;
+ security: SecuritySettings;
+}
+
+export interface GeneralSettings {
+ name: string;
+ languages: Language[];
+}
+
+type Language = {
+ [key: string]: string;
+};
+
+export type LanguageKey = 'en';
+
+export interface MailSettings {
+ host: string;
+ port: number;
+ username: string;
+ password: string;
+ encryption: string;
+ fromAddress: string;
+ fromName: string;
+}
+
+export interface SecuritySettings {
+ recaptcha: {
+ enabled: boolean;
+ siteKey: string;
+ secretKey: string;
+ };
+ '2faEnabled': boolean;
+}
+
+export const getSettings = () => {
+ return useSWR('settings', async () => {
+ const { data } = await http.get(`/api/application/settings`);
+
+ return Transformers.toSettings(data);
+ });
+};
diff --git a/resources/scripts/api/definitions/admin/transformers.ts b/resources/scripts/api/definitions/admin/transformers.ts
index d298341e83..31a345d2d1 100644
--- a/resources/scripts/api/definitions/admin/transformers.ts
+++ b/resources/scripts/api/definitions/admin/transformers.ts
@@ -6,6 +6,7 @@ import * as Models from '@definitions/admin/models';
import { Location } from '@/api/admin/location';
import { Egg, EggVariable } from '@/api/admin/egg';
import { Nest } from '@/api/admin/nest';
+import { Settings } from '@/api/admin/settings';
const isList = (data: FractalResponseList | FractalResponseData): data is FractalResponseList => data.object === 'list';
@@ -225,4 +226,29 @@ export default class Transformers {
eggs: transform(attributes.relationships?.eggs as FractalResponseList, this.toEgg),
},
});
+
+ static toSettings = ({ attributes }: FractalResponseData): Settings => ({
+ general: {
+ name: attributes.general.name,
+ languages: attributes.general.languages,
+ },
+ mail: {
+ host: attributes.mail.host,
+ port: attributes.mail.port,
+ username: attributes.mail.username,
+ password: attributes.mail.password,
+ encryption: attributes.mail.encryption,
+ fromAddress: attributes.mail.from_address,
+ fromName: attributes.mail.from_name,
+ },
+ security: {
+ recaptcha: {
+ enabled: attributes.security.recaptcha.enabled,
+ siteKey: attributes.security.recaptcha.site_key,
+ secretKey: attributes.security.recaptcha.secret_key,
+ },
+ '2faEnabled': attributes.security['2fa_enabled'],
+ },
+ relationships: {},
+ });
}
diff --git a/resources/scripts/components/admin/settings/GeneralSettings.tsx b/resources/scripts/components/admin/settings/GeneralSettings.tsx
index c030f710bf..ca980f489b 100644
--- a/resources/scripts/components/admin/settings/GeneralSettings.tsx
+++ b/resources/scripts/components/admin/settings/GeneralSettings.tsx
@@ -6,8 +6,13 @@ import Field, { FieldRow } from '@/components/elements/Field';
import { useStoreState } from 'easy-peasy';
import { ApplicationStore } from '@/state';
import SelectField from '@/components/elements/SelectField';
+import { GeneralSettings } from '@/api/admin/settings';
-export default () => {
+interface Props {
+ data?: GeneralSettings;
+}
+
+export default ({ data }: Props) => {
const { name: appName, locale: language } = useStoreState((state: ApplicationStore) => state.settings.data!);
const submit = () => {
@@ -20,7 +25,6 @@ export default () => {
initialValues={{
appName,
language,
- googleAnalytics: '',
}}
>