From 5c08ab34ea5964003b5ecdfae8573c2907ced0c5 Mon Sep 17 00:00:00 2001
From: nyne
Date: Wed, 14 May 2025 21:50:59 +0800
Subject: [PATCH] Add server configuration management.
---
frontend/src/components/alert.tsx | 13 ++-
frontend/src/components/input.tsx | 22 +++++
frontend/src/network/models.ts | 9 ++
frontend/src/network/network.ts | 29 +++++-
frontend/src/pages/manage_page.tsx | 8 +-
.../src/pages/manage_server_config_page.tsx | 92 +++++++++++++++++++
frontend/src/pages/resource_details_page.tsx | 6 +-
main.go | 8 +-
server/api/config.go | 64 +++++++++++++
server/api/file.go | 3 +-
server/config/config.go | 76 +++++++++++++++
server/service/file.go | 19 ++--
server/service/resource.go | 2 +-
server/service/storage.go | 9 +-
server/service/user.go | 4 +
server/service/utils.go | 2 +-
16 files changed, 337 insertions(+), 29 deletions(-)
create mode 100644 frontend/src/components/input.tsx
create mode 100644 frontend/src/pages/manage_server_config_page.tsx
create mode 100644 server/api/config.go
create mode 100644 server/config/config.go
diff --git a/frontend/src/components/alert.tsx b/frontend/src/components/alert.tsx
index a36277c..0999d4d 100644
--- a/frontend/src/components/alert.tsx
+++ b/frontend/src/components/alert.tsx
@@ -1,8 +1,17 @@
-export function ErrorAlert({message, className}: {message: string, className?: string}) {
+export function ErrorAlert({ message, className }: { message: string, className?: string }) {
return
+
{message}
+
;
+}
+
+export function InfoAlert({ message, className }: { message: string, className?: string }) {
+ return ;
diff --git a/frontend/src/components/input.tsx b/frontend/src/components/input.tsx
new file mode 100644
index 0000000..45079d8
--- /dev/null
+++ b/frontend/src/components/input.tsx
@@ -0,0 +1,22 @@
+interface InputProps {
+ type?: string;
+ placeholder?: string;
+ value: string;
+ onChange: (e: React.ChangeEvent) => void;
+ label: string;
+ inlineLabel?: boolean;
+}
+
+export default function Input(props: InputProps) {
+ if (props.inlineLabel) {
+ return
+ } else {
+ return
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/network/models.ts b/frontend/src/network/models.ts
index 40ee67c..0d1c67a 100644
--- a/frontend/src/network/models.ts
+++ b/frontend/src/network/models.ts
@@ -108,3 +108,12 @@ export interface CommentWithResource {
user: User;
resource: Resource;
}
+
+export interface ServerConfig {
+ max_uploading_size_in_mb: number;
+ max_file_size_in_mb: number;
+ max_downloads_per_day_for_single_ip: number;
+ allow_register: boolean;
+ cloudflare_turnstile_site_key: string;
+ cloudflare_turnstile_secret_key: string;
+}
diff --git a/frontend/src/network/network.ts b/frontend/src/network/network.ts
index dcd7819..b9d9ca9 100644
--- a/frontend/src/network/network.ts
+++ b/frontend/src/network/network.ts
@@ -13,7 +13,8 @@ import {
User,
UserWithToken,
Comment,
- CommentWithResource
+ CommentWithResource,
+ ServerConfig
} from "./models.ts";
class Network {
@@ -635,6 +636,32 @@ class Network {
return { success: false, message: e.toString() };
}
}
+
+ async getServerConfig(): Promise> {
+ try {
+ const response = await axios.get(`${this.apiBaseUrl}/config`);
+ return response.data;
+ } catch (e: any) {
+ console.error(e);
+ return {
+ success: false,
+ message: e.toString(),
+ };
+ }
+ }
+
+ async setServerConfig(config: ServerConfig): Promise> {
+ try {
+ const response = await axios.post(`${this.apiBaseUrl}/config`, config);
+ return response.data;
+ } catch (e: any) {
+ console.error(e);
+ return {
+ success: false,
+ message: e.toString(),
+ };
+ }
+ }
}
export const network = new Network();
diff --git a/frontend/src/pages/manage_page.tsx b/frontend/src/pages/manage_page.tsx
index 1185bc6..1bbc342 100644
--- a/frontend/src/pages/manage_page.tsx
+++ b/frontend/src/pages/manage_page.tsx
@@ -4,6 +4,7 @@ import StorageView from "./manage_storage_page.tsx";
import UserView from "./manage_user_page.tsx";
import { useTranslation } from "react-i18next";
import { ManageMePage } from "./manage_me_page.tsx";
+import ManageServerConfigPage from "./manage_server_config_page.tsx";
export default function ManagePage() {
const { t } = useTranslation();
@@ -43,13 +44,15 @@ export default function ManagePage() {
const pageNames = [
t("My Info"),
t("Storage"),
- t("Users")
+ t("Users"),
+ t("Server"),
]
const pageComponents = [
,
,
-
+ ,
+ ,
]
return
@@ -80,6 +83,7 @@ export default function ManagePage() {
{buildItem(t("My Info"), , 0)}
{buildItem(t("Storage"), , 1)}
{buildItem(t("Users"), , 2)}
+ {buildItem(t("Server"), , 3)}
diff --git a/frontend/src/pages/manage_server_config_page.tsx b/frontend/src/pages/manage_server_config_page.tsx
new file mode 100644
index 0000000..f5b54f5
--- /dev/null
+++ b/frontend/src/pages/manage_server_config_page.tsx
@@ -0,0 +1,92 @@
+import { useTranslation } from "react-i18next";
+import { app } from "../app"
+import { ErrorAlert, InfoAlert } from "../components/alert"
+import { useEffect, useState } from "react";
+import { ServerConfig } from "../network/models";
+import Loading from "../components/loading";
+import Input from "../components/input";
+import { network } from "../network/network";
+import showToast from "../components/toast";
+import Button from "../components/button";
+
+export default function ManageServerConfigPage() {
+ const { t } = useTranslation();
+
+ const [config, setConfig] = useState(null);
+
+ const [isLoading, setIsLoading] = useState(false);
+
+ useEffect(() => {
+ network.getServerConfig().then((res) => {
+ if (res.success) {
+ setConfig(res.data!);
+ } else {
+ showToast({
+ message: res.message,
+ type: "error",
+ })
+ }
+ })
+ }, []);
+
+ if (!app.user) {
+ return
+ }
+
+ if (!app.user?.is_admin) {
+ return
+ }
+
+ if (config == null) {
+ return
+ }
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ if (isLoading) {
+ return;
+ }
+ setIsLoading(true);
+ const res = await network.setServerConfig(config);
+ if (res.success) {
+ showToast({
+ message: t("Update server config successfully"),
+ type: "success",
+ });
+ } else {
+ showToast({
+ message: res.message,
+ type: "error",
+ });
+ }
+ setIsLoading(false);
+ };
+
+ return
+}
\ No newline at end of file
diff --git a/frontend/src/pages/resource_details_page.tsx b/frontend/src/pages/resource_details_page.tsx
index ad9eeb2..657f7b0 100644
--- a/frontend/src/pages/resource_details_page.tsx
+++ b/frontend/src/pages/resource_details_page.tsx
@@ -96,7 +96,7 @@ export default function ResourcePage() {
}
-