fix(panel): streamline system settings and server creation

Use shared action buttons and default to the login space. Allow staff to save startup-only experience settings while running and request a durable restart through the existing operator flow.

Grant the API PVC list permission needed to detect retained worlds before server creation, and show internal failures with a request ID. Cover permission, maintenance, restart and UI behavior with regression checks.
This commit is contained in:
Lemon-miaow committed 2026-10-04 16:26:03 +08:00
1 parent e67896979e
commit cb3ed94026
34 files changed
+555 -103

No files matched your search

+3
View File
@@ -529,6 +529,9 @@ func write(r *os.Root, name string, content []byte, sum, expect string, createOn
if res.Code != "" {
return res
}
if name == naming.ExperienceConfigFile && target != name {
return Result{Code: CodeBadPath, Error: "the experience config must be a regular file, not a symlink"}
}
if expect != "" {
if res := checkUnchanged(r, name, target, expect); res.Code != "" {
return res
+15
View File
@@ -45,6 +45,21 @@ func run(root, op, path string, content []byte, expect string) (Result, error) {
return Execute(root, Request{Op: op, Path: path, Content: content, Expect: expect})
}
func TestExperienceConfigCannotWriteThroughSymlink(t *testing.T) {
root, _ := worldRoot(t)
if err := os.Symlink("server.properties", filepath.Join(root, "felis-experience.json")); err != nil {
t.Fatal(err)
}
res, err := run(root, OpWrite, "felis-experience.json", []byte("{}"), "")
if err != nil || res.Code != CodeBadPath {
t.Fatalf("symlink write: result=%+v err=%v", res, err)
}
content, err := os.ReadFile(filepath.Join(root, "server.properties"))
if err != nil || string(content) != "motd=hello\n" {
t.Fatalf("live world file was changed: content=%q err=%v", content, err)
}
}
// TestExecuteContainment is the security test of this package. The world directory
// holds attacker-influenced content (players and plugins create files in it), so
// each vector below is a path a caller could genuinely supply to try to leave the