mirror of
				https://github.com/v2board/v2board.git
				synced 2025-11-01 01:41:47 +08:00 
			
		
		
		
	| @@ -39,7 +39,7 @@ class ConfigController extends Controller | ||||
|     public function testSendMail(Request $request) | ||||
|     { | ||||
|         $obj = new SendEmailJob([ | ||||
|             'email' => $request->session()->get('email'), | ||||
|             'email' => $request->user['email'], | ||||
|             'subject' => 'This is v2board test email', | ||||
|             'template_name' => 'notify', | ||||
|             'template_value' => [ | ||||
|   | ||||
| @@ -8,6 +8,7 @@ use App\Utils\Helper; | ||||
| use Illuminate\Http\Request; | ||||
| use App\Http\Controllers\Controller; | ||||
| use App\Models\Payment; | ||||
| use Illuminate\Support\Facades\DB; | ||||
|  | ||||
| class PaymentController extends Controller | ||||
| { | ||||
| @@ -24,7 +25,7 @@ class PaymentController extends Controller | ||||
|  | ||||
|     public function fetch() | ||||
|     { | ||||
|         $payments = Payment::all(); | ||||
|         $payments = Payment::orderBy('sort', 'ASC')->get(); | ||||
|         foreach ($payments as $k => $v) { | ||||
|             $notifyUrl = url("/api/v1/guest/payment/notify/{$v->payment}/{$v->uuid}"); | ||||
|             if ($v->notify_domain) { | ||||
| @@ -107,4 +108,26 @@ class PaymentController extends Controller | ||||
|             'data' => $payment->delete() | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public function sort(Request $request) | ||||
|     { | ||||
|         $request->validate([ | ||||
|             'ids' => 'required|array' | ||||
|         ], [ | ||||
|             'ids.required' => '参数有误', | ||||
|             'ids.array' => '参数有误' | ||||
|         ]); | ||||
|         DB::beginTransaction(); | ||||
|         foreach ($request->input('ids') as $k => $v) { | ||||
|             if (!Payment::find($v)->update(['sort' => $k + 1])) { | ||||
|                 DB::rollBack(); | ||||
|                 abort(500, '保存失败'); | ||||
|             } | ||||
|         } | ||||
|         DB::commit(); | ||||
|         return response([ | ||||
|             'data' => true | ||||
|         ]); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin; | ||||
| use App\Http\Requests\Admin\PlanSave; | ||||
| use App\Http\Requests\Admin\PlanSort; | ||||
| use App\Http\Requests\Admin\PlanUpdate; | ||||
| use App\Services\PlanService; | ||||
| use Illuminate\Http\Request; | ||||
| use App\Http\Controllers\Controller; | ||||
| use App\Models\Plan; | ||||
| @@ -16,17 +17,7 @@ class PlanController extends Controller | ||||
| { | ||||
|     public function fetch(Request $request) | ||||
|     { | ||||
|         $counts = User::select( | ||||
|             DB::raw("plan_id"), | ||||
|             DB::raw("count(*) as count") | ||||
|         ) | ||||
|             ->where('plan_id', '!=', NULL) | ||||
|             ->where(function ($query) { | ||||
|                 $query->where('expired_at', '>=', time()) | ||||
|                     ->orWhere('expired_at', NULL); | ||||
|             }) | ||||
|             ->groupBy("plan_id") | ||||
|             ->get(); | ||||
|         $counts = PlanService::countActiveUsers(); | ||||
|         $plans = Plan::orderBy('sort', 'ASC')->get(); | ||||
|         foreach ($plans as $k => $v) { | ||||
|             $plans[$k]->count = 0; | ||||
|   | ||||
| @@ -89,13 +89,4 @@ class V2rayController extends Controller | ||||
|             'data' => true | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function viewConfig(Request $request) | ||||
|     { | ||||
|         $serverService = new ServerService(); | ||||
|         $config = $serverService->getV2RayConfig($request->input('node_id'), 23333); | ||||
|         return response([ | ||||
|             'data' => $config | ||||
|         ]); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin; | ||||
|  | ||||
| use App\Models\ServerShadowsocks; | ||||
| use App\Models\ServerTrojan; | ||||
| use App\Models\StatUser; | ||||
| use App\Services\ServerService; | ||||
| use Illuminate\Http\Request; | ||||
| use App\Http\Controllers\Controller; | ||||
| @@ -45,7 +46,15 @@ class StatController extends Controller | ||||
|                 'last_month_income' => Order::where('created_at', '>=', strtotime('-1 month', strtotime(date('Y-m-1')))) | ||||
|                     ->where('created_at', '<', strtotime(date('Y-m-1'))) | ||||
|                     ->whereNotIn('status', [0, 2]) | ||||
|                     ->sum('total_amount') | ||||
|                     ->sum('total_amount'), | ||||
|                 'commission_month_payout' => Order::where('actual_commission_balance' ,'!=', NULL) | ||||
|                     ->where('created_at', '>=', strtotime(date('Y-m-1'))) | ||||
|                     ->where('created_at', '<', time()) | ||||
|                     ->sum('actual_commission_balance'), | ||||
|                 'commission_last_month_payout' => Order::where('actual_commission_balance' ,'!=', NULL) | ||||
|                     ->where('created_at', '>=', strtotime('-1 month', strtotime(date('Y-m-1')))) | ||||
|                     ->where('created_at', '<', strtotime(date('Y-m-1'))) | ||||
|                     ->sum('actual_commission_balance'), | ||||
|             ] | ||||
|         ]); | ||||
|     } | ||||
| @@ -123,5 +132,23 @@ class StatController extends Controller | ||||
|             'data' => $statistics | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getStatUser(Request $request) | ||||
|     { | ||||
|         $request->validate([ | ||||
|             'user_id' => 'required|integer' | ||||
|         ]); | ||||
|         $current = $request->input('current') ? $request->input('current') : 1; | ||||
|         $pageSize = $request->input('pageSize') >= 10 ? $request->input('pageSize') : 10; | ||||
|         $builder = StatUser::orderBy('record_at', 'DESC')->where('user_id', $request->input('user_id')); | ||||
|  | ||||
|         $total = $builder->count(); | ||||
|         $records = $builder->forPage($current, $pageSize) | ||||
|             ->get(); | ||||
|         return [ | ||||
|             'data' => $records, | ||||
|             'total' => $total | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -19,11 +19,16 @@ use App\Models\StatServer; | ||||
| use Illuminate\Support\Facades\Cache; | ||||
| use Illuminate\Support\Facades\DB; | ||||
| use Illuminate\Support\Facades\Http; | ||||
| use Laravel\Horizon\Contracts\JobRepository; | ||||
| use Laravel\Horizon\Contracts\MasterSupervisorRepository; | ||||
| use Laravel\Horizon\Contracts\MetricsRepository; | ||||
| use Laravel\Horizon\Contracts\SupervisorRepository; | ||||
| use Laravel\Horizon\Contracts\WorkloadRepository; | ||||
| use Laravel\Horizon\WaitTimeCalculator; | ||||
|  | ||||
| class SystemController extends Controller | ||||
| { | ||||
|     public function getStatus() | ||||
|     public function getSystemStatus() | ||||
|     { | ||||
|         return response([ | ||||
|             'data' => [ | ||||
| @@ -33,6 +38,13 @@ class SystemController extends Controller | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function getQueueWorkload(WorkloadRepository $workload) | ||||
|     { | ||||
|         return response([ | ||||
|             'data' => collect($workload->get())->sortBy('name')->values()->toArray() | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     protected function getScheduleStatus():bool | ||||
|     { | ||||
|         return (time() - 120) < Cache::get(CacheKey::get('SCHEDULE_LAST_CHECK_AT', null)); | ||||
| @@ -48,5 +60,56 @@ class SystemController extends Controller | ||||
|             return $master->status === 'paused'; | ||||
|         }) ? false : true; | ||||
|     } | ||||
|  | ||||
|     public function getQueueStats() | ||||
|     { | ||||
|         return response([ | ||||
|             'data' => [ | ||||
|                 'failedJobs' => app(JobRepository::class)->countRecentlyFailed(), | ||||
|                 'jobsPerMinute' => app(MetricsRepository::class)->jobsProcessedPerMinute(), | ||||
|                 'pausedMasters' => $this->totalPausedMasters(), | ||||
|                 'periods' => [ | ||||
|                     'failedJobs' => config('horizon.trim.recent_failed', config('horizon.trim.failed')), | ||||
|                     'recentJobs' => config('horizon.trim.recent'), | ||||
|                 ], | ||||
|                 'processes' => $this->totalProcessCount(), | ||||
|                 'queueWithMaxRuntime' => app(MetricsRepository::class)->queueWithMaximumRuntime(), | ||||
|                 'queueWithMaxThroughput' => app(MetricsRepository::class)->queueWithMaximumThroughput(), | ||||
|                 'recentJobs' => app(JobRepository::class)->countRecent(), | ||||
|                 'status' => $this->getHorizonStatus(), | ||||
|                 'wait' => collect(app(WaitTimeCalculator::class)->calculate())->take(1), | ||||
|             ] | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the total process count across all supervisors. | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     protected function totalProcessCount() | ||||
|     { | ||||
|         $supervisors = app(SupervisorRepository::class)->all(); | ||||
|  | ||||
|         return collect($supervisors)->reduce(function ($carry, $supervisor) { | ||||
|             return $carry + collect($supervisor->processes)->sum(); | ||||
|         }, 0); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the number of master supervisors that are currently paused. | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     protected function totalPausedMasters() | ||||
|     { | ||||
|         if (! $masters = app(MasterSupervisorRepository::class)->all()) { | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         return collect($masters)->filter(function ($master) { | ||||
|             return $master->status === 'paused'; | ||||
|         })->count(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -68,7 +68,7 @@ class TicketController extends Controller | ||||
|         $ticketService->replyByAdmin( | ||||
|             $request->input('id'), | ||||
|             $request->input('message'), | ||||
|             $request->session()->get('id') | ||||
|             $request->user['id'] | ||||
|         ); | ||||
|         return response([ | ||||
|             'data' => true | ||||
|   | ||||
| @@ -24,6 +24,7 @@ class Clash | ||||
|         header("subscription-userinfo: upload={$user['u']}; download={$user['d']}; total={$user['transfer_enable']}; expire={$user['expired_at']}"); | ||||
|         header('profile-update-interval: 24'); | ||||
|         header("content-disposition:attachment;filename*=UTF-8''".rawurlencode($appName)); | ||||
|         header("profile-web-page-url:" . config('v2board.app_url')); | ||||
|         $defaultConfig = base_path() . '/resources/rules/default.clash.yaml'; | ||||
|         $customConfig = base_path() . '/resources/rules/custom.clash.yaml'; | ||||
|         if (\File::exists($customConfig)) { | ||||
| @@ -121,7 +122,6 @@ class Clash | ||||
|                     $array['ws-opts']['path'] = $wsSettings['path']; | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) | ||||
|                     $array['ws-opts']['headers'] = ['Host' => $wsSettings['headers']['Host']]; | ||||
|                 // TODO: 2022.06.01 remove it | ||||
|                 if (isset($wsSettings['path']) && !empty($wsSettings['path'])) | ||||
|                     $array['ws-path'] = $wsSettings['path']; | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) | ||||
|   | ||||
| @@ -122,7 +122,6 @@ class Stash | ||||
|                     $array['ws-opts']['path'] = $wsSettings['path']; | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) | ||||
|                     $array['ws-opts']['headers'] = ['Host' => $wsSettings['headers']['Host']]; | ||||
|                 // TODO: 2022.06.01 remove it | ||||
|                 if (isset($wsSettings['path']) && !empty($wsSettings['path'])) | ||||
|                     $array['ws-path'] = $wsSettings['path']; | ||||
|                 if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) | ||||
| @@ -155,6 +154,11 @@ class Stash | ||||
|         return $array; | ||||
|     } | ||||
|  | ||||
|     private function isRegex($exp) | ||||
|     { | ||||
|         return @preg_match($exp, null) !== false; | ||||
|     } | ||||
|  | ||||
|     private function isMatch($exp, $str) | ||||
|     { | ||||
|         try { | ||||
|   | ||||
| @@ -21,6 +21,9 @@ class Surfboard | ||||
|         $servers = $this->servers; | ||||
|         $user = $this->user; | ||||
|  | ||||
|         $appName = config('v2board.app_name', 'V2Board'); | ||||
|         header("content-disposition:attachment;filename*=UTF-8''".rawurlencode($appName).".conf"); | ||||
|  | ||||
|         $proxies = ''; | ||||
|         $proxyGroup = ''; | ||||
|  | ||||
|   | ||||
| @@ -21,6 +21,9 @@ class Surge | ||||
|         $servers = $this->servers; | ||||
|         $user = $this->user; | ||||
|  | ||||
|         $appName = config('v2board.app_name', 'V2Board'); | ||||
|         header("content-disposition:attachment;filename*=UTF-8''".rawurlencode($appName).".conf"); | ||||
|  | ||||
|         $proxies = ''; | ||||
|         $proxyGroup = ''; | ||||
|  | ||||
|   | ||||
| @@ -10,25 +10,28 @@ class TelegramController extends Controller | ||||
| { | ||||
|     protected $msg; | ||||
|     protected $commands = []; | ||||
|     protected $telegramService; | ||||
|  | ||||
|     public function __construct(Request $request) | ||||
|     { | ||||
|         if ($request->input('access_token') !== md5(config('v2board.telegram_bot_token'))) { | ||||
|             abort(401); | ||||
|         } | ||||
|  | ||||
|         $this->telegramService = new TelegramService(); | ||||
|     } | ||||
|  | ||||
|     public function webhook(Request $request) | ||||
|     { | ||||
|         $this->msg = $this->getMessage($request->input()); | ||||
|         if (!$this->msg) return; | ||||
|         $this->formatMessage($request->input()); | ||||
|         $this->formatChatJoinRequest($request->input()); | ||||
|         $this->handle(); | ||||
|     } | ||||
|  | ||||
|     public function handle() | ||||
|     { | ||||
|         if (!$this->msg) return; | ||||
|         $msg = $this->msg; | ||||
|  | ||||
|         $commandName = explode('@', $msg->command); | ||||
|  | ||||
|         // To reduce request, only commands contains @ will get the bot name | ||||
| @@ -59,34 +62,62 @@ class TelegramController extends Controller | ||||
|                 } | ||||
|             } | ||||
|         } catch (\Exception $e) { | ||||
|             $telegramService = new TelegramService(); | ||||
|             $telegramService->sendMessage($msg->chat_id, $e->getMessage()); | ||||
|             $this->telegramService->sendMessage($msg->chat_id, $e->getMessage()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function getBotName() | ||||
|     { | ||||
|         $telegramService = new TelegramService(); | ||||
|         $response = $telegramService->getMe(); | ||||
|         $response = $this->telegramService->getMe(); | ||||
|         return $response->result->username; | ||||
|     } | ||||
|  | ||||
|     private function getMessage(array $data) | ||||
|     private function formatMessage(array $data) | ||||
|     { | ||||
|         if (!isset($data['message'])) return false; | ||||
|         if (!isset($data['message'])) return; | ||||
|         if (!isset($data['message']['text'])) return; | ||||
|         $obj = new \StdClass(); | ||||
|         if (!isset($data['message']['text'])) return false; | ||||
|         $text = explode(' ', $data['message']['text']); | ||||
|         $obj->command = $text[0]; | ||||
|         $obj->args = array_slice($text, 1); | ||||
|         $obj->chat_id = $data['message']['chat']['id']; | ||||
|         $obj->message_id = $data['message']['message_id']; | ||||
|         $obj->message_type = !isset($data['message']['reply_to_message']['text']) ? 'message' : 'reply_message'; | ||||
|         $obj->message_type = 'message'; | ||||
|         $obj->text = $data['message']['text']; | ||||
|         $obj->is_private = $data['message']['chat']['type'] === 'private'; | ||||
|         if ($obj->message_type === 'reply_message') { | ||||
|         if (isset($data['message']['reply_to_message']['text'])) { | ||||
|             $obj->message_type = 'reply_message'; | ||||
|             $obj->reply_text = $data['message']['reply_to_message']['text']; | ||||
|         } | ||||
|         return $obj; | ||||
|         $this->msg = $obj; | ||||
|     } | ||||
|  | ||||
|     private function formatChatJoinRequest(array $data) | ||||
|     { | ||||
|         if (!isset($data['chat_join_request'])) return; | ||||
|         if (!isset($data['chat_join_request']['from']['id'])) return; | ||||
|         if (!isset($data['chat_join_request']['chat']['id'])) return; | ||||
|         $user = \App\Models\User::where('telegram_id', $data['chat_join_request']['from']['id']) | ||||
|             ->first(); | ||||
|         if (!$user) { | ||||
|             $this->telegramService->declineChatJoinRequest( | ||||
|                 $data['chat_join_request']['chat']['id'], | ||||
|                 $data['chat_join_request']['from']['id'] | ||||
|             ); | ||||
|             return; | ||||
|         } | ||||
|         $userService = new \App\Services\UserService(); | ||||
|         if (!$userService->isAvailable($user)) { | ||||
|             $this->telegramService->declineChatJoinRequest( | ||||
|                 $data['chat_join_request']['chat']['id'], | ||||
|                 $data['chat_join_request']['from']['id'] | ||||
|             ); | ||||
|             return; | ||||
|         } | ||||
|         $userService = new \App\Services\UserService(); | ||||
|         $this->telegramService->approveChatJoinRequest( | ||||
|             $data['chat_join_request']['chat']['id'], | ||||
|             $data['chat_join_request']['from']['id'] | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -6,6 +6,7 @@ use App\Http\Controllers\Controller; | ||||
| use App\Http\Requests\Passport\AuthRegister; | ||||
| use App\Http\Requests\Passport\AuthForget; | ||||
| use App\Http\Requests\Passport\AuthLogin; | ||||
| use App\Jobs\SendEmailJob; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Facades\Cache; | ||||
| use App\Models\Plan; | ||||
| @@ -18,6 +19,59 @@ use ReCaptcha\ReCaptcha; | ||||
|  | ||||
| class AuthController extends Controller | ||||
| { | ||||
|     public function loginWithMailLink(Request $request) | ||||
|     { | ||||
|         if (!(int)config('v2board.login_with_mail_link_enable')) { | ||||
|             abort(404); | ||||
|         } | ||||
|         $params = $request->validate([ | ||||
|             'email' => 'required|email', | ||||
|             'redirect' => 'nullable' | ||||
|         ]); | ||||
|  | ||||
|         if (Cache::get(CacheKey::get('LAST_SEND_LOGIN_WITH_MAIL_LINK_TIMESTAMP', $params['email']))) { | ||||
|             abort(500, __('Sending frequently, please try again later')); | ||||
|         } | ||||
|  | ||||
|         $user = User::where('email', $params['email'])->first(); | ||||
|         if (!$user) { | ||||
|             return response([ | ||||
|                 'data' => true | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         $code = Helper::guid(); | ||||
|         $key = CacheKey::get('TEMP_TOKEN', $code); | ||||
|         Cache::put($key, $user->id, 300); | ||||
|         Cache::put(CacheKey::get('LAST_SEND_LOGIN_WITH_MAIL_LINK_TIMESTAMP', $params['email']), time(), 60); | ||||
|  | ||||
|  | ||||
|         $redirect = '/#/login?verify=' . $code . '&redirect=' . ($request->input('redirect') ? $request->input('redirect') : 'dashboard'); | ||||
|         if (config('v2board.app_url')) { | ||||
|             $link = config('v2board.app_url') . $redirect; | ||||
|         } else { | ||||
|             $link = url($redirect); | ||||
|         } | ||||
|  | ||||
|         SendEmailJob::dispatch([ | ||||
|             'email' => $user->email, | ||||
|             'subject' => __('Login to :name', [ | ||||
|                 'name' => config('v2board.app_name', 'V2Board') | ||||
|             ]), | ||||
|             'template_name' => 'login', | ||||
|             'template_value' => [ | ||||
|                 'name' => config('v2board.app_name', 'V2Board'), | ||||
|                 'link' => $link, | ||||
|                 'url' => config('v2board.app_url') | ||||
|             ] | ||||
|         ]); | ||||
|  | ||||
|         return response([ | ||||
|             'data' => $link | ||||
|         ]); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function register(AuthRegister $request) | ||||
|     { | ||||
|         if ((int)config('v2board.register_limit_by_ip_enable', 0)) { | ||||
| @@ -113,8 +167,7 @@ class AuthController extends Controller | ||||
|             'token' => $user->token, | ||||
|             'auth_data' => base64_encode("{$user->email}:{$user->password}") | ||||
|         ]; | ||||
|         $request->session()->put('email', $user->email); | ||||
|         $request->session()->put('id', $user->id); | ||||
|  | ||||
|         $user->last_login_at = time(); | ||||
|         $user->save(); | ||||
|  | ||||
| @@ -156,16 +209,8 @@ class AuthController extends Controller | ||||
|             'token' => $user->token, | ||||
|             'auth_data' => base64_encode("{$user->email}:{$user->password}") | ||||
|         ]; | ||||
|         $request->session()->put('email', $user->email); | ||||
|         $request->session()->put('id', $user->id); | ||||
|         if ($user->is_admin) { | ||||
|             $request->session()->put('is_admin', true); | ||||
|             $data['is_admin'] = true; | ||||
|         } | ||||
|         if ($user->is_staff) { | ||||
|             $request->session()->put('is_staff', true); | ||||
|             $data['is_staff'] = true; | ||||
|         } | ||||
|  | ||||
|         if ($user->is_admin) $data['is_admin'] = true; | ||||
|         return response([ | ||||
|             'data' => $data | ||||
|         ]); | ||||
| @@ -196,14 +241,13 @@ class AuthController extends Controller | ||||
|             if ($user->banned) { | ||||
|                 abort(500, __('Your account has been suspended')); | ||||
|             } | ||||
|             $request->session()->put('email', $user->email); | ||||
|             $request->session()->put('id', $user->id); | ||||
|             if ($user->is_admin) { | ||||
|                 $request->session()->put('is_admin', true); | ||||
|             } | ||||
|             $data = [ | ||||
|                 'token' => $user->token, | ||||
|                 'auth_data' => base64_encode("{$user->email}:{$user->password}") | ||||
|             ]; | ||||
|             Cache::forget($key); | ||||
|             return response([ | ||||
|                 'data' => true | ||||
|                 'data' => $data | ||||
|             ]); | ||||
|         } | ||||
|     } | ||||
| @@ -225,8 +269,11 @@ class AuthController extends Controller | ||||
|  | ||||
|     public function getQuickLoginUrl(Request $request) | ||||
|     { | ||||
|         $authData = explode(':', base64_decode($request->input('auth_data'))); | ||||
|         if (!isset($authData[0])) abort(403, __('Token error')); | ||||
|         $authorization = $request->input('auth_data') ?? $request->header('authorization'); | ||||
|         if (!$authorization) abort(403, '未登录或登陆已过期'); | ||||
|  | ||||
|         $authData = explode(':', base64_decode($authorization)); | ||||
|         if (!isset($authData[0]) || !isset($authData[1])) abort(403, __('Token error')); | ||||
|         $user = User::where('email', $authData[0]) | ||||
|             ->where('password', $authData[1]) | ||||
|             ->first(); | ||||
| @@ -248,19 +295,6 @@ class AuthController extends Controller | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function check(Request $request) | ||||
|     { | ||||
|         $data = [ | ||||
|             'is_login' => $request->session()->get('id') ? true : false | ||||
|         ]; | ||||
|         if ($request->session()->get('is_admin')) { | ||||
|             $data['is_admin'] = true; | ||||
|         } | ||||
|         return response([ | ||||
|             'data' => $data | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function forget(AuthForget $request) | ||||
|     { | ||||
|         if (Cache::get(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))) !== $request->input('email_code')) { | ||||
| @@ -281,5 +315,4 @@ class AuthController extends Controller | ||||
|             'data' => true | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -17,24 +17,6 @@ use ReCaptcha\ReCaptcha; | ||||
|  | ||||
| class CommController extends Controller | ||||
| { | ||||
|     // TODO: remove on 1.5.5 | ||||
|     public function config() | ||||
|     { | ||||
|         return response([ | ||||
|             'data' => [ | ||||
|                 'isEmailVerify' => (int)config('v2board.email_verify', 0) ? 1 : 0, | ||||
|                 'isInviteForce' => (int)config('v2board.invite_force', 0) ? 1 : 0, | ||||
|                 'emailWhitelistSuffix' => (int)config('v2board.email_whitelist_enable', 0) | ||||
|                     ? $this->getEmailSuffix() | ||||
|                     : 0, | ||||
|                 'isRecaptcha' => (int)config('v2board.recaptcha_enable', 0) ? 1 : 0, | ||||
|                 'recaptchaSiteKey' => config('v2board.recaptcha_site_key'), | ||||
|                 'appDescription' => config('v2board.app_description'), | ||||
|                 'appUrl' => config('v2board.app_url') | ||||
|             ] | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     private function isEmailVerify() | ||||
|     { | ||||
|         return response([ | ||||
|   | ||||
| @@ -82,9 +82,9 @@ class DeepbworkController extends Controller | ||||
|         Cache::put(CacheKey::get('SERVER_V2RAY_LAST_PUSH_AT', $server->id), time(), 3600); | ||||
|         $userService = new UserService(); | ||||
|         foreach ($data as $item) { | ||||
|             $u = $item['u'] * $server->rate; | ||||
|             $d = $item['d'] * $server->rate; | ||||
|             $userService->trafficFetch($u, $d, $item['user_id'], $server, 'vmess'); | ||||
|             $u = $item['u']; | ||||
|             $d = $item['d']; | ||||
|             $userService->trafficFetch($u, $d, $item['user_id'], $server->toArray(), 'vmess'); | ||||
|         } | ||||
|  | ||||
|         return response([ | ||||
|   | ||||
| @@ -74,9 +74,9 @@ class ShadowsocksTidalabController extends Controller | ||||
|         Cache::put(CacheKey::get('SERVER_SHADOWSOCKS_LAST_PUSH_AT', $server->id), time(), 3600); | ||||
|         $userService = new UserService(); | ||||
|         foreach ($data as $item) { | ||||
|             $u = $item['u'] * $server->rate; | ||||
|             $d = $item['d'] * $server->rate; | ||||
|             $userService->trafficFetch($u, $d, $item['user_id'], $server, 'shadowsocks'); | ||||
|             $u = $item['u']; | ||||
|             $d = $item['d']; | ||||
|             $userService->trafficFetch($u, $d, $item['user_id'], $server->toArray(), 'shadowsocks'); | ||||
|         } | ||||
|  | ||||
|         return response([ | ||||
|   | ||||
| @@ -79,9 +79,9 @@ class TrojanTidalabController extends Controller | ||||
|         Cache::put(CacheKey::get('SERVER_TROJAN_LAST_PUSH_AT', $server->id), time(), 3600); | ||||
|         $userService = new UserService(); | ||||
|         foreach ($data as $item) { | ||||
|             $u = $item['u'] * $server->rate; | ||||
|             $d = $item['d'] * $server->rate; | ||||
|             $userService->trafficFetch($u, $d, $item['user_id'], $server, 'trojan'); | ||||
|             $u = $item['u']; | ||||
|             $d = $item['d']; | ||||
|             $userService->trafficFetch($u, $d, $item['user_id'], $server->toArray(), 'trojan'); | ||||
|         } | ||||
|  | ||||
|         return response([ | ||||
|   | ||||
| @@ -86,9 +86,9 @@ class VProxyController extends Controller | ||||
|         Cache::put(CacheKey::get('SERVER_' . strtoupper($this->nodeType) . '_LAST_PUSH_AT', $this->nodeInfo->id), time(), 3600); | ||||
|         $userService = new UserService(); | ||||
|         foreach ($data as $item) { | ||||
|             $u = $item['u'] * $this->nodeInfo->rate; | ||||
|             $d = $item['d'] * $this->nodeInfo->rate; | ||||
|             $userService->trafficFetch($u, $d, $item['user_id'], $this->nodeInfo, $this->nodeType); | ||||
|             $u = $item['u']; | ||||
|             $d = $item['d']; | ||||
|             $userService->trafficFetch($u, $d, $item['user_id'], $this->nodeInfo->toArray(), $this->nodeType); | ||||
|         } | ||||
|  | ||||
|         return response([ | ||||
|   | ||||
| @@ -57,7 +57,7 @@ class TicketController extends Controller | ||||
|         $ticketService->replyByAdmin( | ||||
|             $request->input('id'), | ||||
|             $request->input('message'), | ||||
|             $request->session()->get('id') | ||||
|             $request->user['id'] | ||||
|         ); | ||||
|         return response([ | ||||
|             'data' => true | ||||
|   | ||||
| @@ -19,7 +19,11 @@ class CommController extends Controller | ||||
|                 'withdraw_methods' => config('v2board.commission_withdraw_method', Dict::WITHDRAW_METHOD_WHITELIST_DEFAULT), | ||||
|                 'withdraw_close' => (int)config('v2board.withdraw_close_enable', 0), | ||||
|                 'currency' => config('v2board.currency', 'CNY'), | ||||
|                 'currency_symbol' => config('v2board.currency_symbol', '¥') | ||||
|                 'currency_symbol' => config('v2board.currency_symbol', '¥'), | ||||
|                 'commission_distribution_enable' => (int)config('v2board.commission_distribution_enable', 0), | ||||
|                 'commission_distribution_l1' => config('v2board.commission_distribution_l1'), | ||||
|                 'commission_distribution_l2' => config('v2board.commission_distribution_l2'), | ||||
|                 'commission_distribution_l3' => config('v2board.commission_distribution_l3') | ||||
|             ] | ||||
|         ]); | ||||
|     } | ||||
|   | ||||
| @@ -16,7 +16,7 @@ class CouponController extends Controller | ||||
|         } | ||||
|         $couponService = new CouponService($request->input('code')); | ||||
|         $couponService->setPlanId($request->input('plan_id')); | ||||
|         $couponService->setUserId($request->session()->get('id')); | ||||
|         $couponService->setUserId($request->user['id']); | ||||
|         $couponService->check(); | ||||
|         return response([ | ||||
|             'data' => $couponService->getCoupon() | ||||
|   | ||||
| @@ -14,11 +14,11 @@ class InviteController extends Controller | ||||
| { | ||||
|     public function save(Request $request) | ||||
|     { | ||||
|         if (InviteCode::where('user_id', $request->session()->get('id'))->where('status', 0)->count() >= config('v2board.invite_gen_limit', 5)) { | ||||
|         if (InviteCode::where('user_id', $request->user['id'])->where('status', 0)->count() >= config('v2board.invite_gen_limit', 5)) { | ||||
|             abort(500, __('The maximum number of creations has been reached')); | ||||
|         } | ||||
|         $inviteCode = new InviteCode(); | ||||
|         $inviteCode->user_id = $request->session()->get('id'); | ||||
|         $inviteCode->user_id = $request->user['id']; | ||||
|         $inviteCode->code = Helper::randomChar(8); | ||||
|         return response([ | ||||
|             'data' => $inviteCode->save() | ||||
| @@ -27,42 +27,49 @@ class InviteController extends Controller | ||||
|  | ||||
|     public function details(Request $request) | ||||
|     { | ||||
|         $current = $request->input('current') ? $request->input('current') : 1; | ||||
|         $pageSize = $request->input('page_size') >= 10 ? $request->input('page_size') : 10; | ||||
|         $builder = CommissionLog::where('invite_user_id', $request->user['id']) | ||||
|             ->where('get_amount', '>', 0) | ||||
|             ->select([ | ||||
|                 'id', | ||||
|                 'trade_no', | ||||
|                 'order_amount', | ||||
|                 'get_amount', | ||||
|                 'created_at' | ||||
|             ]) | ||||
|             ->orderBy('created_at', 'DESC'); | ||||
|         $total = $builder->count(); | ||||
|         $details = $builder->forPage($current, $pageSize) | ||||
|             ->get(); | ||||
|         return response([ | ||||
|             'data' => CommissionLog::where('invite_user_id', $request->session()->get('id')) | ||||
|                 ->where('get_amount', '>', 0) | ||||
|                 ->select([ | ||||
|                     'id', | ||||
|                     'trade_no', | ||||
|                     'order_amount', | ||||
|                     'get_amount', | ||||
|                     'created_at' | ||||
|                 ]) | ||||
|                 ->get() | ||||
|             'data' => $details, | ||||
|             'total' => $total | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function fetch(Request $request) | ||||
|     { | ||||
|         $codes = InviteCode::where('user_id', $request->session()->get('id')) | ||||
|         $codes = InviteCode::where('user_id', $request->user['id']) | ||||
|             ->where('status', 0) | ||||
|             ->get(); | ||||
|         $commission_rate = config('v2board.invite_commission', 10); | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         if ($user->commission_rate) { | ||||
|             $commission_rate = $user->commission_rate; | ||||
|         } | ||||
|         $stat = [ | ||||
|             //已注册用户数 | ||||
|             (int)User::where('invite_user_id', $request->session()->get('id'))->count(), | ||||
|             (int)User::where('invite_user_id', $request->user['id'])->count(), | ||||
|             //有效的佣金 | ||||
|             (int)Order::where('status', 3) | ||||
|                 ->where('commission_status', 2) | ||||
|                 ->where('invite_user_id', $request->session()->get('id')) | ||||
|                 ->where('invite_user_id', $request->user['id']) | ||||
|                 ->sum('commission_balance'), | ||||
|             //确认中的佣金 | ||||
|             (int)Order::where('status', 3) | ||||
|                 ->where('commission_status', 0) | ||||
|                 ->where('invite_user_id', $request->session()->get('id')) | ||||
|                 ->where('invite_user_id', $request->user['id']) | ||||
|                 ->sum('commission_balance'), | ||||
|             //佣金比例 | ||||
|             (int)$commission_rate, | ||||
|   | ||||
| @@ -19,14 +19,9 @@ class KnowledgeController extends Controller | ||||
|                 ->first() | ||||
|                 ->toArray(); | ||||
|             if (!$knowledge) abort(500, __('Article does not exist')); | ||||
|             $user = User::find($request->session()->get('id')); | ||||
|             $user = User::find($request->user['id']); | ||||
|             $userService = new UserService(); | ||||
|             if ($userService->isAvailable($user)) { | ||||
|                 $appleId = config('v2board.apple_id'); | ||||
|                 $appleIdPassword = config('v2board.apple_id_password'); | ||||
|             } else { | ||||
|                 $appleId = __('No active subscription. Unable to use our provided Apple ID'); | ||||
|                 $appleIdPassword = __('No active subscription. Unable to use our provided Apple ID'); | ||||
|             if (!$userService->isAvailable($user)) { | ||||
|                 $this->formatAccessData($knowledge['body']); | ||||
|             } | ||||
|             $subscribeUrl = Helper::getSubscribeUrl("/api/v1/client/subscribe?token={$user['token']}"); | ||||
| @@ -46,11 +41,19 @@ class KnowledgeController extends Controller | ||||
|                 'data' => $knowledge | ||||
|             ]); | ||||
|         } | ||||
|         $knowledges = Knowledge::select(['id', 'category', 'title', 'updated_at']) | ||||
|         $builder = Knowledge::select(['id', 'category', 'title', 'updated_at']) | ||||
|             ->where('language', $request->input('language')) | ||||
|             ->where('show', 1) | ||||
|             ->orderBy('sort', 'ASC') | ||||
|             ->get() | ||||
|             ->orderBy('sort', 'ASC'); | ||||
|         $keyword = $request->input('keyword'); | ||||
|         if ($keyword) { | ||||
|             $builder = $builder->where(function ($query) use ($keyword) { | ||||
|                 $query->where('title', 'LIKE', "%{$keyword}%") | ||||
|                     ->orWhere('body', 'LIKE', "%{$keyword}%"); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         $knowledges = $builder->get() | ||||
|             ->groupBy('category'); | ||||
|         return response([ | ||||
|             'data' => $knowledges | ||||
|   | ||||
| @@ -9,6 +9,7 @@ use App\Models\Payment; | ||||
| use App\Services\CouponService; | ||||
| use App\Services\OrderService; | ||||
| use App\Services\PaymentService; | ||||
| use App\Services\PlanService; | ||||
| use App\Services\UserService; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Facades\Cache; | ||||
| @@ -28,7 +29,7 @@ class OrderController extends Controller | ||||
| { | ||||
|     public function fetch(Request $request) | ||||
|     { | ||||
|         $model = Order::where('user_id', $request->session()->get('id')) | ||||
|         $model = Order::where('user_id', $request->user['id']) | ||||
|             ->orderBy('created_at', 'DESC'); | ||||
|         if ($request->input('status') !== null) { | ||||
|             $model->where('status', $request->input('status')); | ||||
| @@ -49,7 +50,7 @@ class OrderController extends Controller | ||||
|  | ||||
|     public function detail(Request $request) | ||||
|     { | ||||
|         $order = Order::where('user_id', $request->session()->get('id')) | ||||
|         $order = Order::where('user_id', $request->user['id']) | ||||
|             ->where('trade_no', $request->input('trade_no')) | ||||
|             ->first(); | ||||
|         if (!$order) { | ||||
| @@ -71,28 +72,30 @@ class OrderController extends Controller | ||||
|     public function save(OrderSave $request) | ||||
|     { | ||||
|         $userService = new UserService(); | ||||
|         if ($userService->isNotCompleteOrderByUserId($request->session()->get('id'))) { | ||||
|         if ($userService->isNotCompleteOrderByUserId($request->user['id'])) { | ||||
|             abort(500, __('You have an unpaid or pending order, please try again later or cancel it')); | ||||
|         } | ||||
|  | ||||
|         $plan = Plan::find($request->input('plan_id')); | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $planService = new PlanService($request->input('plan_id')); | ||||
|  | ||||
|         $plan = $planService->plan; | ||||
|         $user = User::find($request->user['id']); | ||||
|  | ||||
|         if (!$plan) { | ||||
|             abort(500, __('Subscription plan does not exist')); | ||||
|         } | ||||
|  | ||||
|         if (!$planService->haveCapacity() && $request->input('period') !== 'reset_price') { | ||||
|             abort(500, __('Current product is sold out')); | ||||
|         } | ||||
|  | ||||
|         if ($plan[$request->input('period')] === NULL) { | ||||
|             abort(500, __('This payment period cannot be purchased, please choose another period')); | ||||
|         } | ||||
|  | ||||
|         if ($request->input('period') === 'reset_price') { | ||||
|             if (!$user->plan_id) { | ||||
|             if (!$userService->isAvailable($user) || $plan->id !== $user->plan_id) { | ||||
|                 abort(500, __('Subscription has expired or no active subscription, unable to purchase Data Reset Package')); | ||||
|             } else { | ||||
|                 if ($user->plan_id !== $plan->id) { | ||||
|                     abort(500, __('This subscription reset package does not apply to your subscription')); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -114,7 +117,7 @@ class OrderController extends Controller | ||||
|         DB::beginTransaction(); | ||||
|         $order = new Order(); | ||||
|         $orderService = new OrderService($order); | ||||
|         $order->user_id = $request->session()->get('id'); | ||||
|         $order->user_id = $request->user['id']; | ||||
|         $order->plan_id = $plan->id; | ||||
|         $order->period = $request->input('period'); | ||||
|         $order->trade_no = Helper::generateOrderNo(); | ||||
| @@ -170,7 +173,7 @@ class OrderController extends Controller | ||||
|         $tradeNo = $request->input('trade_no'); | ||||
|         $method = $request->input('method'); | ||||
|         $order = Order::where('trade_no', $tradeNo) | ||||
|             ->where('user_id', $request->session()->get('id')) | ||||
|             ->where('user_id', $request->user['id']) | ||||
|             ->where('status', 0) | ||||
|             ->first(); | ||||
|         if (!$order) { | ||||
| @@ -209,7 +212,7 @@ class OrderController extends Controller | ||||
|     { | ||||
|         $tradeNo = $request->input('trade_no'); | ||||
|         $order = Order::where('trade_no', $tradeNo) | ||||
|             ->where('user_id', $request->session()->get('id')) | ||||
|             ->where('user_id', $request->user['id']) | ||||
|             ->first(); | ||||
|         if (!$order) { | ||||
|             abort(500, __('Order does not exist')); | ||||
| @@ -229,7 +232,9 @@ class OrderController extends Controller | ||||
|             'handling_fee_fixed', | ||||
|             'handling_fee_percent' | ||||
|         ]) | ||||
|             ->where('enable', 1)->get(); | ||||
|             ->where('enable', 1) | ||||
|             ->orderBy('sort', 'ASC') | ||||
|             ->get(); | ||||
|  | ||||
|         return response([ | ||||
|             'data' => $methods | ||||
| @@ -242,7 +247,7 @@ class OrderController extends Controller | ||||
|             abort(500, __('Invalid parameter')); | ||||
|         } | ||||
|         $order = Order::where('trade_no', $request->input('trade_no')) | ||||
|             ->where('user_id', $request->session()->get('id')) | ||||
|             ->where('user_id', $request->user['id']) | ||||
|             ->first(); | ||||
|         if (!$order) { | ||||
|             abort(500, __('Order does not exist')); | ||||
|   | ||||
| @@ -4,14 +4,16 @@ namespace App\Http\Controllers\User; | ||||
|  | ||||
| use App\Http\Controllers\Controller; | ||||
| use App\Models\User; | ||||
| use App\Services\PlanService; | ||||
| use Illuminate\Http\Request; | ||||
| use App\Models\Plan; | ||||
| use Illuminate\Support\Facades\DB; | ||||
|  | ||||
| class PlanController extends Controller | ||||
| { | ||||
|     public function fetch(Request $request) | ||||
|     { | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         if ($request->input('id')) { | ||||
|             $plan = Plan::where('id', $request->input('id'))->first(); | ||||
|             if (!$plan) { | ||||
| @@ -24,11 +26,18 @@ class PlanController extends Controller | ||||
|                 'data' => $plan | ||||
|             ]); | ||||
|         } | ||||
|         $plan = Plan::where('show', 1) | ||||
|  | ||||
|         $counts = PlanService::countActiveUsers(); | ||||
|         $plans = Plan::where('show', 1) | ||||
|             ->orderBy('sort', 'ASC') | ||||
|             ->get(); | ||||
|         foreach ($plans as $k => $v) { | ||||
|             if ($plans[$k]->capacity_limit === NULL) continue; | ||||
|             if (!isset($counts[$plans[$k]->id])) continue; | ||||
|             $plans[$k]->capacity_limit = $plans[$k]->capacity_limit - $counts[$plans[$k]->id]->count; | ||||
|         } | ||||
|         return response([ | ||||
|             'data' => $plan | ||||
|             'data' => $plans | ||||
|         ]); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,7 @@ class ServerController extends Controller | ||||
| { | ||||
|     public function fetch(Request $request) | ||||
|     { | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         $servers = []; | ||||
|         $userService = new UserService(); | ||||
|         if ($userService->isAvailable($user)) { | ||||
|   | ||||
| @@ -18,7 +18,7 @@ class StatController extends Controller | ||||
|             'user_id', | ||||
|             'server_rate' | ||||
|         ]) | ||||
|             ->where('user_id', $request->session()->get('id')) | ||||
|             ->where('user_id', $request->user['id']) | ||||
|             ->where('record_at', '>=', strtotime(date('Y-m-1'))) | ||||
|             ->orderBy('record_at', 'DESC'); | ||||
|         return response([ | ||||
|   | ||||
| @@ -22,6 +22,6 @@ class TelegramController extends Controller | ||||
|  | ||||
|     public function unbind(Request $request) | ||||
|     { | ||||
|         $user = User::where('user_id', $request->session()->get('id'))->first(); | ||||
|         $user = User::where('user_id', $request->user['id'])->first(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ class TicketController extends Controller | ||||
|     { | ||||
|         if ($request->input('id')) { | ||||
|             $ticket = Ticket::where('id', $request->input('id')) | ||||
|                 ->where('user_id', $request->session()->get('id')) | ||||
|                 ->where('user_id', $request->user['id']) | ||||
|                 ->first(); | ||||
|             if (!$ticket) { | ||||
|                 abort(500, __('Ticket does not exist')); | ||||
| @@ -38,7 +38,7 @@ class TicketController extends Controller | ||||
|                 'data' => $ticket | ||||
|             ]); | ||||
|         } | ||||
|         $ticket = Ticket::where('user_id', $request->session()->get('id')) | ||||
|         $ticket = Ticket::where('user_id', $request->user['id']) | ||||
|             ->orderBy('created_at', 'DESC') | ||||
|             ->get(); | ||||
|         return response([ | ||||
| @@ -49,21 +49,21 @@ class TicketController extends Controller | ||||
|     public function save(TicketSave $request) | ||||
|     { | ||||
|         DB::beginTransaction(); | ||||
|         if ((int)Ticket::where('status', 0)->where('user_id', $request->session()->get('id'))->lockForUpdate()->count()) { | ||||
|         if ((int)Ticket::where('status', 0)->where('user_id', $request->user['id'])->lockForUpdate()->count()) { | ||||
|             abort(500, __('There are other unresolved tickets')); | ||||
|         } | ||||
|         $ticket = Ticket::create(array_merge($request->only([ | ||||
|             'subject', | ||||
|             'level' | ||||
|         ]), [ | ||||
|             'user_id' => $request->session()->get('id') | ||||
|             'user_id' => $request->user['id'] | ||||
|         ])); | ||||
|         if (!$ticket) { | ||||
|             DB::rollback(); | ||||
|             abort(500, __('Failed to open ticket')); | ||||
|         } | ||||
|         $ticketMessage = TicketMessage::create([ | ||||
|             'user_id' => $request->session()->get('id'), | ||||
|             'user_id' => $request->user['id'], | ||||
|             'ticket_id' => $ticket->id, | ||||
|             'message' => $request->input('message') | ||||
|         ]); | ||||
| @@ -87,7 +87,7 @@ class TicketController extends Controller | ||||
|             abort(500, __('Message cannot be empty')); | ||||
|         } | ||||
|         $ticket = Ticket::where('id', $request->input('id')) | ||||
|             ->where('user_id', $request->session()->get('id')) | ||||
|             ->where('user_id', $request->user['id']) | ||||
|             ->first(); | ||||
|         if (!$ticket) { | ||||
|             abort(500, __('Ticket does not exist')); | ||||
| @@ -95,14 +95,14 @@ class TicketController extends Controller | ||||
|         if ($ticket->status) { | ||||
|             abort(500, __('The ticket is closed and cannot be replied')); | ||||
|         } | ||||
|         if ($request->session()->get('id') == $this->getLastMessage($ticket->id)->user_id) { | ||||
|         if ($request->user['id'] == $this->getLastMessage($ticket->id)->user_id) { | ||||
|             abort(500, __('Please wait for the technical enginneer to reply')); | ||||
|         } | ||||
|         $ticketService = new TicketService(); | ||||
|         if (!$ticketService->reply( | ||||
|             $ticket, | ||||
|             $request->input('message'), | ||||
|             $request->session()->get('id') | ||||
|             $request->user['id'] | ||||
|         )) { | ||||
|             abort(500, __('Ticket reply failed')); | ||||
|         } | ||||
| @@ -119,7 +119,7 @@ class TicketController extends Controller | ||||
|             abort(500, __('Invalid parameter')); | ||||
|         } | ||||
|         $ticket = Ticket::where('id', $request->input('id')) | ||||
|             ->where('user_id', $request->session()->get('id')) | ||||
|             ->where('user_id', $request->user['id']) | ||||
|             ->first(); | ||||
|         if (!$ticket) { | ||||
|             abort(500, __('Ticket does not exist')); | ||||
| @@ -154,7 +154,7 @@ class TicketController extends Controller | ||||
|         )) { | ||||
|             abort(500, __('Unsupported withdrawal method')); | ||||
|         } | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         $limit = config('v2board.commission_withdraw_limit', 100); | ||||
|         if ($limit > ($user->commission_balance / 100)) { | ||||
|             abort(500, __('The current required minimum withdrawal commission is :limit', ['limit' => $limit])); | ||||
| @@ -164,7 +164,7 @@ class TicketController extends Controller | ||||
|         $ticket = Ticket::create([ | ||||
|             'subject' => $subject, | ||||
|             'level' => 2, | ||||
|             'user_id' => $request->session()->get('id') | ||||
|             'user_id' => $request->user['id'] | ||||
|         ]); | ||||
|         if (!$ticket) { | ||||
|             DB::rollback(); | ||||
| @@ -175,7 +175,7 @@ class TicketController extends Controller | ||||
|             __('Withdrawal account') . ":" . $request->input('withdraw_account') | ||||
|         ); | ||||
|         $ticketMessage = TicketMessage::create([ | ||||
|             'user_id' => $request->session()->get('id'), | ||||
|             'user_id' => $request->user['id'], | ||||
|             'ticket_id' => $ticket->id, | ||||
|             'message' => $message | ||||
|         ]); | ||||
|   | ||||
| @@ -18,17 +18,22 @@ use Illuminate\Support\Facades\Cache; | ||||
|  | ||||
| class UserController extends Controller | ||||
| { | ||||
|     public function logout(Request $request) | ||||
|     public function checkLogin(Request $request) | ||||
|     { | ||||
|         $request->session()->flush(); | ||||
|         $data = [ | ||||
|             'is_login' => $request->user['id'] ? true : false | ||||
|         ]; | ||||
|         if ($request->user['is_admin']) { | ||||
|             $data['is_admin'] = true; | ||||
|         } | ||||
|         return response([ | ||||
|             'data' => true | ||||
|             'data' => $data | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     public function changePassword(UserChangePassword $request) | ||||
|     { | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         if (!$user) { | ||||
|             abort(500, __('The user does not exist')); | ||||
|         } | ||||
| @@ -46,7 +51,6 @@ class UserController extends Controller | ||||
|         if (!$user->save()) { | ||||
|             abort(500, __('Save failed')); | ||||
|         } | ||||
|         $request->session()->flush(); | ||||
|         return response([ | ||||
|             'data' => true | ||||
|         ]); | ||||
| @@ -54,7 +58,7 @@ class UserController extends Controller | ||||
|  | ||||
|     public function info(Request $request) | ||||
|     { | ||||
|         $user = User::where('id', $request->session()->get('id')) | ||||
|         $user = User::where('id', $request->user['id']) | ||||
|             ->select([ | ||||
|                 'email', | ||||
|                 'transfer_enable', | ||||
| @@ -86,12 +90,12 @@ class UserController extends Controller | ||||
|     { | ||||
|         $stat = [ | ||||
|             Order::where('status', 0) | ||||
|                 ->where('user_id', $request->session()->get('id')) | ||||
|                 ->where('user_id', $request->user['id']) | ||||
|                 ->count(), | ||||
|             Ticket::where('status', 0) | ||||
|                 ->where('user_id', $request->session()->get('id')) | ||||
|                 ->where('user_id', $request->user['id']) | ||||
|                 ->count(), | ||||
|             User::where('invite_user_id', $request->session()->get('id')) | ||||
|             User::where('invite_user_id', $request->user['id']) | ||||
|                 ->count() | ||||
|         ]; | ||||
|         return response([ | ||||
| @@ -101,7 +105,7 @@ class UserController extends Controller | ||||
|  | ||||
|     public function getSubscribe(Request $request) | ||||
|     { | ||||
|         $user = User::where('id', $request->session()->get('id')) | ||||
|         $user = User::where('id', $request->user['id']) | ||||
|             ->select([ | ||||
|                 'plan_id', | ||||
|                 'token', | ||||
| @@ -131,7 +135,7 @@ class UserController extends Controller | ||||
|  | ||||
|     public function resetSecurity(Request $request) | ||||
|     { | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         if (!$user) { | ||||
|             abort(500, __('The user does not exist')); | ||||
|         } | ||||
| @@ -152,7 +156,7 @@ class UserController extends Controller | ||||
|             'remind_traffic' | ||||
|         ]); | ||||
|  | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         if (!$user) { | ||||
|             abort(500, __('The user does not exist')); | ||||
|         } | ||||
| @@ -169,7 +173,7 @@ class UserController extends Controller | ||||
|  | ||||
|     public function transfer(UserTransfer $request) | ||||
|     { | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         if (!$user) { | ||||
|             abort(500, __('The user does not exist')); | ||||
|         } | ||||
| @@ -188,7 +192,7 @@ class UserController extends Controller | ||||
|  | ||||
|     public function getQuickLoginUrl(Request $request) | ||||
|     { | ||||
|         $user = User::find($request->session()->get('id')); | ||||
|         $user = User::find($request->user['id']); | ||||
|         if (!$user) { | ||||
|             abort(500, __('The user does not exist')); | ||||
|         } | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| namespace App\Http; | ||||
|  | ||||
| use Fruitcake\Cors\HandleCors; | ||||
| use Illuminate\Foundation\Http\Kernel as HttpKernel; | ||||
|  | ||||
| class Kernel extends HttpKernel | ||||
| @@ -14,6 +15,7 @@ class Kernel extends HttpKernel | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $middleware = [ | ||||
|         \App\Http\Middleware\CORS::class, | ||||
|         \App\Http\Middleware\TrustProxies::class, | ||||
|         \App\Http\Middleware\CheckForMaintenanceMode::class, | ||||
|         \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, | ||||
| @@ -28,22 +30,20 @@ class Kernel extends HttpKernel | ||||
|      */ | ||||
|     protected $middlewareGroups = [ | ||||
|         'web' => [ | ||||
|             \App\Http\Middleware\EncryptCookies::class, | ||||
|             \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, | ||||
|             \Illuminate\Session\Middleware\StartSession::class, | ||||
| //            \App\Http\Middleware\EncryptCookies::class, | ||||
| //            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, | ||||
| //            \Illuminate\Session\Middleware\StartSession::class, | ||||
|             // \Illuminate\Session\Middleware\AuthenticateSession::class, | ||||
|             \Illuminate\View\Middleware\ShareErrorsFromSession::class, | ||||
|             \App\Http\Middleware\VerifyCsrfToken::class, | ||||
|             \Illuminate\Routing\Middleware\SubstituteBindings::class, | ||||
|             \App\Http\Middleware\CORS::class, | ||||
| //            \Illuminate\View\Middleware\ShareErrorsFromSession::class, | ||||
| //            \App\Http\Middleware\VerifyCsrfToken::class, | ||||
| //            \Illuminate\Routing\Middleware\SubstituteBindings::class, | ||||
|         ], | ||||
|  | ||||
|         'api' => [ | ||||
|             \App\Http\Middleware\EncryptCookies::class, | ||||
|             \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, | ||||
|             \Illuminate\Session\Middleware\StartSession::class, | ||||
| //            \App\Http\Middleware\EncryptCookies::class, | ||||
| //            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, | ||||
| //            \Illuminate\Session\Middleware\StartSession::class, | ||||
|             \App\Http\Middleware\ForceJson::class, | ||||
|             \App\Http\Middleware\CORS::class, | ||||
|             \App\Http\Middleware\Language::class, | ||||
|             'bindings', | ||||
|         ], | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| namespace App\Http\Middleware; | ||||
|  | ||||
| use Closure; | ||||
| use Illuminate\Support\Facades\Cache; | ||||
|  | ||||
| class Admin | ||||
| { | ||||
| @@ -15,9 +16,28 @@ class Admin | ||||
|      */ | ||||
|     public function handle($request, Closure $next) | ||||
|     { | ||||
|         if (!$request->session()->get('is_admin')) { | ||||
|             abort(403, '权限不足'); | ||||
|         $authorization = $request->input('auth_data') ?? $request->header('authorization'); | ||||
|         if (!$authorization) abort(403, '未登录或登陆已过期'); | ||||
|  | ||||
|         $authData = explode(':', base64_decode($authorization)); | ||||
|         if (!Cache::has($authorization)) { | ||||
|             if (!isset($authData[1]) || !isset($authData[0])) abort(403, '鉴权失败,请重新登入'); | ||||
|             $user = \App\Models\User::where('password', $authData[1]) | ||||
|                 ->where('email', $authData[0]) | ||||
|                 ->select([ | ||||
|                     'id', | ||||
|                     'email', | ||||
|                     'is_admin', | ||||
|                     'is_staff' | ||||
|                 ]) | ||||
|                 ->first(); | ||||
|             if (!$user) abort(403, '鉴权失败,请重新登入'); | ||||
|             if (!$user->is_admin) abort(403, '鉴权失败,请重新登入'); | ||||
|             Cache::put($authorization, $user->toArray(), 3600); | ||||
|         } | ||||
|         $request->merge([ | ||||
|             'user' => Cache::get($authorization) | ||||
|         ]); | ||||
|         return $next($request); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -17,8 +17,8 @@ class CORS | ||||
|         } | ||||
|         $response = $next($request); | ||||
|         $response->header('Access-Control-Allow-Origin', trim($origin, '/')); | ||||
|         $response->header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS'); | ||||
|         $response->header('Access-Control-Allow-Headers', 'Content-Type,X-Requested-With'); | ||||
|         $response->header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS,HEAD'); | ||||
|         $response->header('Access-Control-Allow-Headers', 'Origin,Content-Type,Accept,Authorization,X-Request-With'); | ||||
|         $response->header('Access-Control-Allow-Credentials', 'true'); | ||||
|         $response->header('Access-Control-Max-Age', 10080); | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,9 @@ class Client | ||||
|         if (!$user) { | ||||
|             abort(403, 'token is error'); | ||||
|         } | ||||
|         $request->user = $user; | ||||
|         $request->merge([ | ||||
|             'user' => $user | ||||
|         ]); | ||||
|         return $next($request); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| namespace App\Http\Middleware; | ||||
|  | ||||
| use Closure; | ||||
| use Illuminate\Support\Facades\Cache; | ||||
|  | ||||
| class Staff | ||||
| { | ||||
| @@ -15,9 +16,28 @@ class Staff | ||||
|      */ | ||||
|     public function handle($request, Closure $next) | ||||
|     { | ||||
|         if (!$request->session()->get('is_staff')) { | ||||
|             abort(403, '权限不足'); | ||||
|         $authorization = $request->input('auth_data') ?? $request->header('authorization'); | ||||
|         if (!$authorization) abort(403, '未登录或登陆已过期'); | ||||
|  | ||||
|         $authData = explode(':', base64_decode($authorization)); | ||||
|         if (!Cache::has($authorization)) { | ||||
|             if (!isset($authData[1]) || !isset($authData[0])) abort(403, '鉴权失败,请重新登入'); | ||||
|             $user = \App\Models\User::where('password', $authData[1]) | ||||
|                 ->where('email', $authData[0]) | ||||
|                 ->select([ | ||||
|                     'id', | ||||
|                     'email', | ||||
|                     'is_admin', | ||||
|                     'is_staff' | ||||
|                 ]) | ||||
|                 ->first(); | ||||
|             if (!$user) abort(403, '鉴权失败,请重新登入'); | ||||
|             if (!$user->is_staff) abort(403, '鉴权失败,请重新登入'); | ||||
|             Cache::put($authorization, $user->toArray(), 3600); | ||||
|         } | ||||
|         $request->merge([ | ||||
|             'user' => Cache::get($authorization) | ||||
|         ]); | ||||
|         return $next($request); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| namespace App\Http\Middleware; | ||||
|  | ||||
| use Closure; | ||||
| use Illuminate\Support\Facades\Cache; | ||||
|  | ||||
| class User | ||||
| { | ||||
| @@ -16,19 +17,26 @@ class User | ||||
|     public function handle($request, Closure $next) | ||||
|     { | ||||
|         $authorization = $request->input('auth_data') ?? $request->header('authorization'); | ||||
|         if ($authorization) { | ||||
|             $authData = explode(':', base64_decode($authorization)); | ||||
|         if (!$authorization) abort(403, '未登录或登陆已过期'); | ||||
|  | ||||
|         $authData = explode(':', base64_decode($authorization)); | ||||
|         if (!Cache::has($authorization)) { | ||||
|             if (!isset($authData[1]) || !isset($authData[0])) abort(403, '鉴权失败,请重新登入'); | ||||
|             $user = \App\Models\User::where('password', $authData[1]) | ||||
|                 ->where('email', $authData[0]) | ||||
|                 ->select([ | ||||
|                     'id', | ||||
|                     'email', | ||||
|                     'is_admin', | ||||
|                     'is_staff' | ||||
|                 ]) | ||||
|                 ->first(); | ||||
|             if (!$user) abort(403, '鉴权失败,请重新登入'); | ||||
|             $request->session()->put('email', $user->email); | ||||
|             $request->session()->put('id', $user->id); | ||||
|         } | ||||
|         if (!$request->session()->get('id')) { | ||||
|             abort(403, '未登录或登陆已过期'); | ||||
|             Cache::put($authorization, $user->toArray(), 3600); | ||||
|         } | ||||
|         $request->merge([ | ||||
|             'user' => Cache::get($authorization) | ||||
|         ]); | ||||
|         return $next($request); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -26,7 +26,8 @@ class PlanSave extends FormRequest | ||||
|             'three_year_price' => 'nullable|integer', | ||||
|             'onetime_price' => 'nullable|integer', | ||||
|             'reset_price' => 'nullable|integer', | ||||
|             'reset_traffic_method' => 'nullable|integer|in:0,1,2,3,4' | ||||
|             'reset_traffic_method' => 'nullable|integer|in:0,1,2,3,4', | ||||
|             'capacity_limit' => 'nullable|integer' | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
| @@ -47,7 +48,8 @@ class PlanSave extends FormRequest | ||||
|             'onetime_price.integer' => '一次性金额有误', | ||||
|             'reset_price.integer' => '流量重置包金额有误', | ||||
|             'reset_traffic_method.integer' => '流量重置方式格式有误', | ||||
|             'reset_traffic_method.in' => '流量重置方式格式有误' | ||||
|             'reset_traffic_method.in' => '流量重置方式格式有误', | ||||
|             'capacity_limit.integer' => '容纳用户量限制格式有误' | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -50,7 +50,6 @@ class AdminRoute | ||||
|                 $router->post('update', 'Admin\\Server\\V2rayController@update'); | ||||
|                 $router->post('copy', 'Admin\\Server\\V2rayController@copy'); | ||||
|                 $router->post('sort', 'Admin\\Server\\V2rayController@sort'); | ||||
|                 $router->post('viewConfig', 'Admin\\Server\\V2rayController@viewConfig'); | ||||
|             }); | ||||
|             $router->group([ | ||||
|                 'prefix' => 'server/shadowsocks' | ||||
| @@ -83,6 +82,7 @@ class AdminRoute | ||||
|             $router->get ('/stat/getOverride', 'Admin\\StatController@getOverride'); | ||||
|             $router->get ('/stat/getServerLastRank', 'Admin\\StatController@getServerLastRank'); | ||||
|             $router->get ('/stat/getOrder', 'Admin\\StatController@getOrder'); | ||||
|             $router->get ('/stat/getStatUser', 'Admin\\StatController@getStatUser'); | ||||
|             // Notice | ||||
|             $router->get ('/notice/fetch', 'Admin\\NoticeController@fetch'); | ||||
|             $router->post('/notice/save', 'Admin\\NoticeController@save'); | ||||
| @@ -112,8 +112,12 @@ class AdminRoute | ||||
|             $router->post('/payment/save', 'Admin\\PaymentController@save'); | ||||
|             $router->post('/payment/drop', 'Admin\\PaymentController@drop'); | ||||
|             $router->post('/payment/show', 'Admin\\PaymentController@show'); | ||||
|             $router->post('/payment/sort', 'Admin\\PaymentController@sort'); | ||||
|             // System | ||||
|             $router->get ('/system/getStatus', 'Admin\\SystemController@getStatus'); | ||||
|             $router->get ('/system/getSystemStatus', 'Admin\\SystemController@getSystemStatus'); | ||||
|             $router->get ('/system/getQueueStats', 'Admin\\SystemController@getQueueStats'); | ||||
|             $router->get ('/system/getQueueWorkload', 'Admin\\SystemController@getQueueWorkload'); | ||||
|             $router->get ('/system/getQueueMasters', '\\Laravel\\Horizon\\Http\\Controllers\\MasterSupervisorController@index'); | ||||
|             // Theme | ||||
|             $router->get ('/theme/getThemes', 'Admin\\ThemeController@getThemes'); | ||||
|             $router->post('/theme/saveThemeConfig', 'Admin\\ThemeController@saveThemeConfig'); | ||||
|   | ||||
| @@ -14,12 +14,10 @@ class PassportRoute | ||||
|             $router->post('/auth/register', 'Passport\\AuthController@register'); | ||||
|             $router->post('/auth/login', 'Passport\\AuthController@login'); | ||||
|             $router->get ('/auth/token2Login', 'Passport\\AuthController@token2Login'); | ||||
|             $router->get ('/auth/check', 'Passport\\AuthController@check'); | ||||
|             $router->post('/auth/forget', 'Passport\\AuthController@forget'); | ||||
|             $router->post('/auth/getTempToken', 'Passport\\AuthController@getTempToken'); | ||||
|             $router->post('/auth/getQuickLoginUrl', 'Passport\\AuthController@getQuickLoginUrl'); | ||||
|             $router->post('/auth/loginWithMailLink', 'Passport\\AuthController@loginWithMailLink'); | ||||
|             // Comm | ||||
|             $router->get ('/comm/config', 'Passport\\CommController@config'); | ||||
|             $router->post('/comm/sendEmailVerify', 'Passport\\CommController@sendEmailVerify'); | ||||
|             $router->post('/comm/pv', 'Passport\\CommController@pv'); | ||||
|         }); | ||||
|   | ||||
| @@ -13,21 +13,19 @@ class UserRoute | ||||
|         ], function ($router) { | ||||
|             // User | ||||
|             $router->get ('/resetSecurity', 'User\\UserController@resetSecurity'); | ||||
|             $router->get ('/logout', 'User\\UserController@logout'); | ||||
|             $router->get ('/info', 'User\\UserController@info'); | ||||
|             $router->post('/changePassword', 'User\\UserController@changePassword'); | ||||
|             $router->post('/update', 'User\\UserController@update'); | ||||
|             $router->get ('/getSubscribe', 'User\\UserController@getSubscribe'); | ||||
|             $router->get ('/getStat', 'User\\UserController@getStat'); | ||||
|             $router->get ('/checkLogin', 'User\\UserController@checkLogin'); | ||||
|             $router->post('/transfer', 'User\\UserController@transfer'); | ||||
|             $router->post('/getQuickLoginUrl', 'User\\UserController@getQuickLoginUrl'); | ||||
|             // Order | ||||
|             $router->post('/order/save', 'User\\OrderController@save'); | ||||
|             $router->post('/order/checkout', 'User\\OrderController@checkout'); | ||||
|             $router->get ('/order/check', 'User\\OrderController@check'); | ||||
|             // TODO: 1.5.6 remove | ||||
|             $router->get ('/order/details', 'User\\OrderController@detail'); | ||||
|             // TODO: 1.5.6 remove | ||||
|             $router->get ('/order/details', 'User\\OrderController@detail');                                            // TODO: 1.7.0 remove | ||||
|             $router->get ('/order/detail', 'User\\OrderController@detail'); | ||||
|             $router->get ('/order/fetch', 'User\\OrderController@fetch'); | ||||
|             $router->get ('/order/getPaymentMethod', 'User\\OrderController@getPaymentMethod'); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user