first(); $siteData = SiteContext::current(); $banidos = DB::table('chat_banned_users') ->where('room_id', '=', session('serverID') . '_' . session('siteID'))->count(); return view('site.chat', [ 'userLogged' => $userLogged, 'allNotifications' => DB::table('notifications')->orderBy('id', 'desc')->limit(3)->get(), 'topHref' => 'interat', 'siteData' => $siteData, 'chatUrl' => $this->chatAdminUrl($siteData, $userLogged), 'totalBanned' => $banidos, ]); } /** * Primeiro nome de quem entra, para a sala mostrar quem esta moderando. */ private function adminName(?User $user): string { $nome = trim((string) ($user->name ?? '')); return $nome === '' ? 'Administrador' : explode(' ', $nome)[0]; } private function chatAdminUrl(object $siteData, ?User $user): string { $payload = json_encode([ 'room' => $siteData->server_id . '_' . $siteData->id, 'name' => $this->adminName($user), 'exp' => now()->addHours(config('chat.token_hours'))->timestamp, ]); $body = $this->base64Url($payload); $sign = $this->base64Url(hash_hmac('sha256', $body, config('chat.secret'), true)); return config('chat.url') . '?' . http_build_query([ 'id' => $siteData->id, 's' => $siteData->server_id, 'adm' => $body . '.' . $sign, ]); } private function base64Url(string $raw): string { return rtrim(strtr(base64_encode($raw), '+/', '-_'), '='); } /** A sala a que o bloqueio pertence: servidor e site, sempre da sessao. */ private function chatRoom(): string { return session('serverID') . '_' . session('siteID'); } /** * Os banidos passaram a ser resolvidos num modal dentro do bate-papo. A * pagina antiga vira um atalho para la, para quem tiver o endereco salvo. */ public function chatBan() { return redirect()->route('site.chat.r'); } /** * Lista os banidos da sala. E uma lista curta por natureza, entao vem * inteira, com um teto para o dia em que nao for. */ public function chatBanList(Request $request) { $total = DB::table('chat_banned_users')->where('room_id', '=', $this->chatRoom())->count(); /** * O botao do bate-papo so precisa do numero. Pedir a lista inteira para * mostrar um contador seria trazer duzias de linhas a toa. */ if ($request->query('only') === 'count') { return response()->json(['total' => $total]); } $banidos = DB::table('chat_banned_users')->where('room_id', '=', $this->chatRoom()) ->orderBy('id', 'desc')->limit(self::BAN_LIMIT + 1)->get(); return response()->json([ 'total' => $total, 'capped' => $banidos->count() > self::BAN_LIMIT, 'items' => $banidos->take(self::BAN_LIMIT)->map(function ($ban) { return [ 'id' => $ban->id, 'name' => $ban->user_id, 'when' => date('d/m/Y H:i', strtotime($ban->banned_at)), 'ago' => time_ago($ban->banned_at), ]; })->values(), ]); } public function setBanChat($server, $siteID , $names, $ip){ if(!$siteID || !$ip){ return response()->json(array('status' => false, 'error' => '0'), 200); } $expNames = explode('|',$names); $name = (isset($expNames[0]) ? $expNames[0] : ''); $adm = (isset($expNames[1]) ? $expNames[1] : ''); $isBanned = DB::connection('mysql_site_' . $server)->table('chat_ban')->where('site_id', '=', $siteID)->where('ip','=',$ip)->get()->count(); $limitDate = date('Y-m-d H:i:s', strtotime(date('Y-m-d H:i:s'). '+24 hours')); if(!$isBanned){ DB::connection('mysql_site_' . $server)->table('chat_ban')->insert([ 'site_id' => $siteID, 'adm' => $adm, 'ip' => $ip, 'name' => $name, 'created_at' => NOW(), 'limit_date' => $limitDate ]); } return response()->json(array('status' => true), 200); } public function checkChat($server, $siteID , $ip) { if(!$siteID || !$ip){ return response()->json(array('status' => false, 'error' => '0'), 200); } $isBanned = DB::connection('mysql_site_' . $server)->table('chat_ban')->where('site_id', '=', $siteID)->where('ip','=',$ip)->get()->count(); if($isBanned){ return response()->json(array('status' => false, 'error' => '1'), 200); } return response()->json(array('status' => true), 200); } public function chatUnban() { //Usuário desbloqueado com sucesso! } public function destroyBan(Request $request, $id = null) { $apagou = DB::table('chat_banned_users') ->where('room_id', '=', $this->chatRoom())->where('id', '=', $id)->delete(); if ($request->wantsJson()) { return response()->json([ 'ok' => (bool) $apagou, 'total' => DB::table('chat_banned_users')->where('room_id', '=', $this->chatRoom())->count(), ], $apagou ? 200 : 404); } return redirect()->route('site.chat.r')->with('success', __('site.page_chat_ban_removed')); } /** * A tela nao olha mais o nome do navegador para decidir se transmite: quem * decide e o proprio navegador, testando getUserMedia. A lista fixa de * Chrome e Firefox barrava Edge, Safari, Opera e Brave, que transmitem. */ public function camera() { $siteData = SiteContext::current(); return view('site.camera', [ 'userLogged' => User::where('id', '=', Auth::id())->first(), 'allNotifications' => DB::table('notifications')->orderBy('id', 'desc')->limit(3)->get(), 'siteData' => $siteData, 'topHref' => 'interat', ]); } /* Every sites server has its own bans; one server down must not stop the others */ public function robot() { $now = date('Y-m-d H:i:s'); $failures = []; foreach (array_keys(config('database.connections')) as $connection) { if (! str_starts_with($connection, 'mysql_site_')) { continue; } try { DB::connection($connection)->table('chat_ban')->where('limit_date', '<=', $now)->delete(); } catch (\Throwable $e) { $failures[] = $connection . ': ' . $e->getMessage(); } } if ($failures) { throw new \RuntimeException('chatban falhou em ' . implode(' | ', $failures)); } } public function actBD($type, $siteID, $user,$adm, $data) { if($type == 'insert'){ /*DB::connection('mysql_site_' . session('serverID'))->table('chat_ban')->insert([ 'site_id' => $siteID, 'adm' => $adm, 'ip' => filter_var($data, FILTER_SANITIZE_STRING), 'name' => $user, 'created_at' => NOW(), 'limit_date' => date('Y-m-d H:i:s', strtotime( '+24 hours' , strtotime(date('Y-m-d H:i:s')))) ]);*/ $getall = DB::connection('mysql_site_' . session('serverID'))->table('chat_ban')->where('site_id','=',$siteID) ->where('limit_date' ,'>',NOW())->get(); $do = []; foreach($getall as $item){ $do[] = $item->ip; } $post = [ 'ip' => http_build_query($do), 'site_id' => $siteID, ]; $ch = curl_init(config('chat.blacklist_url')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $response = curl_exec($ch); curl_close($ch); var_dump($response); } } }