Browse Source

完善工单/节点/系统设置的请求合规检测

兔姬桑 4 years ago
parent
commit
2bedbd6b59

+ 10 - 7
app/Http/Controllers/Admin/NodeController.php

@@ -14,6 +14,7 @@ use App\Models\NodeCertificate;
 use App\Models\NodePing;
 use App\Models\RuleGroup;
 use App\Services\NodeService;
+use Arr;
 use Exception;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
@@ -68,7 +69,9 @@ class NodeController extends Controller
     public function store(NodeRequest $request): JsonResponse
     {
         try {
-            $node = Node::create($request->except('_token', 'labels'));
+            $array = $request->validated();
+            Arr::forget($array, ['labels']);
+            $node = Node::create($array);
 
             if ($node) {
                 // 生成节点标签
@@ -104,10 +107,12 @@ class NodeController extends Controller
     public function update(NodeRequest $request, Node $node): JsonResponse
     {
         try {
-            // 更新节点标签
-            $node->labels()->sync($request->input('labels'));
+            $array = $request->validated();
+            Arr::forget($array, ['labels']);
+            if ($node->update($array)) {
+                // 更新节点标签
+                $node->labels()->sync($request->input('labels'));
 
-            if ($node->update($request->except('_token', 'labels'))) {
                 return Response::json(['status' => 'success', 'message' => '编辑成功']);
             }
         } catch (Exception $e) {
@@ -182,9 +187,7 @@ class NodeController extends Controller
     // Ping节点延迟
     public function pingNode(Node $node): JsonResponse
     {
-        $result = NetworkDetection::ping($node->is_ddns ? $node->server : $node->ip);
-
-        if ($result) {
+        if ($result = NetworkDetection::ping($node->is_ddns ? $node->server : $node->ip)) {
             return Response::json([
                 'status' => 'success',
                 'message' => [

+ 9 - 18
app/Http/Controllers/Admin/SystemController.php

@@ -4,11 +4,11 @@ namespace App\Http\Controllers\Admin;
 
 use App\Components\PushNotification;
 use App\Http\Controllers\Controller;
+use App\Http\Requests\Admin\SystemRequest;
 use App\Models\Config;
 use App\Models\Label;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\RedirectResponse;
-use Illuminate\Http\Request;
 use Response;
 
 class SystemController extends Controller
@@ -20,7 +20,7 @@ class SystemController extends Controller
     }
 
     // 设置系统扩展信息,例如客服、统计代码
-    public function setExtend(Request $request): RedirectResponse
+    public function setExtend(SystemRequest $request): RedirectResponse
     {
         if ($request->hasFile('website_home_logo')) {
             $validator = validator()->make($request->all(), ['website_home_logo' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048']);
@@ -53,29 +53,18 @@ class SystemController extends Controller
     }
 
     // 设置某个配置项
-    public function setConfig(Request $request): JsonResponse
+    public function setConfig(SystemRequest $request): JsonResponse
     {
         $name = $request->input('name');
         $value = $request->input('value');
 
-        if (! $name) {
-            return Response::json(['status' => 'fail', 'message' => '设置失败:请求参数异常']);
-        }
-
-        // 屏蔽异常配置
-        if (! in_array($name, Config::pluck('name')->toArray(), true)) {
-            return Response::json(['status' => 'fail', 'message' => '设置失败:配置不存在']);
-        }
-
         // 如果开启用户邮件重置密码,则先设置网站名称和网址
         if ($value !== '0' && in_array($name, ['is_reset_password', 'is_activate_account', 'expire_warning', 'traffic_warning'], true)) {
-            $config = Config::find('website_name');
-            if (! $config->value) {
+            if (! Config::find('website_url')->value) {
                 return Response::json(['status' => 'fail', 'message' => '设置失败:启用该配置需要先设置【网站名称】']);
             }
 
-            $config = Config::find('website_url');
-            if (! $config->value) {
+            if (! Config::find('website_url')->value) {
                 return Response::json(['status' => 'fail', 'message' => '设置失败:启用该配置需要先设置【网站地址】']);
             }
         }
@@ -146,9 +135,11 @@ class SystemController extends Controller
         }
 
         // 更新配置
-        Config::find($name)->update(['value' => $value]);
+        if (Config::findOrFail($name)->update(['value' => $value])) {
+            return Response::json(['status' => 'success', 'message' => '修改成功']);
+        }
 
-        return Response::json(['status' => 'success', 'message' => '操作成功']);
+        return Response::json(['status' => 'fail', 'message' => '修改失败']);
     }
 
     // 推送通知测试

+ 5 - 22
app/Http/Controllers/Admin/TicketController.php

@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
 
 use App\Components\Helpers;
 use App\Http\Controllers\Controller;
+use App\Http\Requests\Admin\TicketRequest;
 use App\Mail\closeTicket;
 use App\Mail\replyTicket;
 use App\Models\Ticket;
@@ -37,34 +38,16 @@ class TicketController extends Controller
     }
 
     // 创建工单
-    public function store(Request $request)
+    public function store(TicketRequest $request)
     {
-        $id = $request->input('id');
-        $email = $request->input('email');
-        $title = $request->input('title');
-        $content = $request->input('content');
-
-        $user = User::find($id) ?: User::whereEmail($email)->first();
-
-        if (! $user) {
-            return Response::json(['status' => 'fail', 'message' => '用户不存在']);
-        }
+        $data = $request->validated();
+        $user = User::find($data['id']) ?: User::whereEmail($data['email'])->first();
 
         if ($user === Auth::user()) {
             return Response::json(['status' => 'fail', 'message' => '不能对自己发起工单']);
         }
 
-        if (empty($title) || empty($content)) {
-            return Response::json(['status' => 'fail', 'message' => '请输入标题和内容']);
-        }
-
-        $obj = new Ticket();
-        $obj->user_id = $user->id;
-        $obj->admin_id = Auth::id();
-        $obj->title = $title;
-        $obj->content = $content;
-
-        if ($obj->save()) {
+        if (Ticket::create(['user_id' => $user->id, 'admin_id' => auth()->id(), 'title' => $data['title'], 'content' => $data['content']])) {
             return Response::json(['status' => 'success', 'message' => '工单创建成功']);
         }
 

+ 30 - 21
app/Http/Requests/Admin/NodeRequest.php

@@ -9,38 +9,47 @@ class NodeRequest extends FormRequest
     public function rules(): array
     {
         return [
-            'type' => 'required|between:1,3',
-            'name' => 'required',
-            'country_code' => 'required',
+            'is_ddns' => 'required|boolean',
+            'name' => 'required|string',
             'server' => 'required_if:is_ddns,1|nullable|ends_with:'.implode(',', config('domains')),
+            'ip' => 'ipv4|required_if:is_ddns,0|nullable',
+            'ipv6' => 'nullable|ipv6',
             'push_port' => 'numeric|between:0,65535',
             'traffic_rate' => 'required|numeric|min:0',
-            'level' => 'required|numeric|between:0,255',
+            'level' => 'required|numeric|exists:level,level',
+            'rule_group_id' => 'nullable|exists:rule_group,id',
             'speed_limit' => 'required|numeric|min:0',
             'client_limit' => 'required|numeric|min:0',
-            'port' => 'nullable|numeric|between:0,65535',
-            'ip' => 'ipv4|required_if:is_ddns,0|nullable',
-            'ipv6' => 'nullable|ipv6',
-            'relay_server' => 'required_if:is_relay,1',
-            'relay_port' => 'required_if:is_relay,1|numeric|between:0,65535',
-            'method' => 'required_if:type,1',
-            'protocol' => 'required_if:type,1',
-            'obfs' => 'required_if:type,1',
-            'is_subscribe' => 'boolean',
-            'is_ddns' => 'boolean',
-            'is_relay' => 'boolean',
-            'is_udp' => 'boolean',
-            'detection_type' => 'between:0,3',
-            'compatible' => 'boolean',
-            'single' => 'boolean',
+            'labels' => 'nullable|exists:label,id',
+            'country_code' => 'required|exists:country,code',
+            'description' => 'nullable|string',
             'sort' => 'required|numeric|between:0,255',
-            'status' => 'boolean',
+            'is_udp' => 'required|boolean',
+            'status' => 'required|boolean',
+            'type' => 'required|numeric|between:1,4',
+            'method' => 'required_if:type,1,4|exists:ss_config,name',
+            'protocol' => 'required_if:type,1,4|exists:ss_config,name',
+            'protocol_param' => 'nullable|string',
+            'obfs' => 'required_if:type,1,4|exists:ss_config,name',
+            'obfs_param' => 'nullable|string',
+            'compatible' => 'required|boolean',
+            'is_subscribe' => 'required|boolean',
+            'detection_type' => 'required|numeric|between:0,3',
+            'single' => 'required|boolean',
+            'port' => 'required_if:single,1|numeric|between:1,65535|nullable',
+            'passwd' => 'required_if:single,1|string|nullable',
             'v2_alter_id' => 'required_if:type,2|numeric|between:0,65535',
             'v2_port' => 'required_if:type,2|numeric|between:0,65535',
             'v2_method' => 'required_if:type,2',
             'v2_net' => 'required_if:type,2',
             'v2_type' => 'required_if:type,2',
-            'v2_tls' => 'boolean',
+            'v2_host' => 'string|nullable',
+            'v2_path' => 'string|nullable',
+            'v2_tls' => 'required_if:type,2|boolean',
+            'tls_provider' => 'json|nullable',
+            'is_relay' => 'required|boolean',
+            'relay_server' => 'required_if:is_relay,1',
+            'relay_port' => 'required_if:is_relay,1|numeric|between:1,65535',
         ];
     }
 

+ 23 - 0
app/Http/Requests/Admin/SystemRequest.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Requests\Admin;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class SystemRequest extends FormRequest
+{
+    public function rules()
+    {
+        return [
+            'name' => 'required|string|exists:config,name',
+            'value' => 'nullable',
+        ];
+    }
+
+    public function messages()
+    {
+        return [
+            'name.exists' => '设置项目不存在于数据库',
+        ];
+    }
+}

+ 18 - 0
app/Http/Requests/Admin/TicketRequest.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Http\Requests\Admin;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class TicketRequest extends FormRequest
+{
+    public function rules()
+    {
+        return [
+            'id' => 'required_without:email|exists:user,id|numeric|nullable',
+            'email' => 'required_without:id|exists:user,email||nullable',
+            'title' => 'required|string',
+            'content' => 'required|string',
+        ];
+    }
+}

+ 0 - 1
resources/views/admin/node/info.blade.php

@@ -107,7 +107,6 @@
                                         <label for="country_code" class="col-md-3 col-form-label"> 国家/地区 </label>
                                         <select data-plugin="selectpicker" data-style="btn-outline btn-primary"
                                                 class="col-md-5 form-control" name="country_code" id="country_code">
-                                            <option value="un" selected hidden>请选择</option>
                                             @foreach($countries as $country)
                                                 <option value="{{$country->code}}">{{$country->code}} - {{$country->name}}</option>
                                             @endforeach

+ 0 - 8
resources/views/admin/rule/index.blade.php

@@ -150,14 +150,6 @@
       @can('admin.rule.store')
       // 添加规则
       function addRule() {
-        $.post("{{route('admin.rule.store')}}", {}, function(ret) {
-          $('#add').modal('hide');
-          if (ret.status === 'success') {
-            swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload());
-          } else {
-            swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
-          }
-        });
         $.ajax({
           method: 'POST',
           url: "{{route('admin.rule.store')}}",

+ 30 - 12
resources/views/admin/ticket/index.blade.php

@@ -177,18 +177,36 @@
           confirmButtonText: '{{trans('home.ticket_confirm')}}',
         }).then((result) => {
           if (result.value) {
-            $.post('{{route('admin.ticket.store')}}', {
-              _token: '{{csrf_token()}}',
-              id: id,
-              email: email,
-              title: title,
-              content: content,
-            }, function(ret) {
-              if (ret.status === 'success') {
-                swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload());
-              } else {
-                swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
-              }
+            $.ajax({
+              method: 'POST',
+              url: "{{route('admin.ticket.store')}}",
+              data: {
+                _token: '{{csrf_token()}}',
+                id: id,
+                email: email,
+                title: title,
+                content: content,
+              },
+              dataType: 'json',
+              success: function(ret) {
+                $('#add_ticket_modal').modal('hide');
+                if (ret.status === 'success') {
+                  swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload());
+                } else {
+                  swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
+                }
+              },
+              error: function(data) {
+                $('#add_ticket_modal').modal('hide');
+                let str = '';
+                const errors = data.responseJSON;
+                if ($.isEmptyObject(errors) === false) {
+                  $.each(errors.errors, function(index, value) {
+                    str += '<li>' + value + '</li>';
+                  });
+                  swal.fire({title: '提示', html: str, icon: 'error', confirmButtonText: '{{trans('home.ticket_confirm')}}'});
+                }
+              },
             });
           }
         });

+ 6 - 1
resources/views/components/chat-unit.blade.php

@@ -1,4 +1,9 @@
-<div class="chat @if(($ticket->admin_id && $ticket->admin_id !== $user->id) ||($ticket->user_id && $ticket->user_id !== $user->id)) chat-left @endif">
+<div class="chat
+@if (isset($ticket->admin_id) && $ticket->admin_id !== $user->id)
+        chat-left
+@elseif(isset($ticket->user_id) && !isset($ticket->admin_id)  && $ticket->user_id !== $user->id)
+        chat-left
+@endif">
     <div class="chat-avatar">
         <p class="avatar" data-toggle="tooltip" href="#" data-placement="right" title="" data-original-title="{{($ticket->admin ?? $ticket->user)->email}}">
             <x-avatar :user="$ticket->admin ?? $ticket->user"/>

+ 1 - 1
resources/views/user/layouts.blade.php

@@ -175,7 +175,7 @@
     <footer class="site-footer">
         <div class="site-footer-legal">
             Copyright ©️2017 - 2020 <a href="https://github.com/ProxyPanel/ProxyPanel" target="_blank">{{config('version.name')}}</a>
-            🚀 版本: {{config('version.number')}}
+            🚀 版本: <code> {{config('version.number')}} </code>
         </div>
         <div class="site-footer-right">
             由 <a href="{{sysConfig('website_url')}}" target="_blank">{{sysConfig('website_name')}}</a> 🈺运营