diff --git a/admin/ConfigWriter.php b/admin/ConfigWriter.php index ef74ac5..bfb3d39 100755 --- a/admin/ConfigWriter.php +++ b/admin/ConfigWriter.php @@ -2,6 +2,8 @@ /** * 生成 check_config/*.php(define 拼接,输出格式与历史 dashboard 一致) */ +require_once dirname(__DIR__) . '/lib/Cloak/CountryAllowlist.php'; + class ConfigWriter { /** @@ -14,7 +16,7 @@ class ConfigWriter $methods = $data['methods']; $blacklist_group_id = (int) $data['blacklist_group_id']; $whitelist_group_id = (int) $data['whitelist_group_id']; - $country = $data['country']; + $country = CountryAllowlist::formatForConfig($data['country']); $show_content = $data['show_content']; $DB_fp = $data['DB_fp']; $costm_ip_score = $data['costm_ip_score']; diff --git a/check_config/indBXSXX_config.php b/check_config/indBXSXX_config.php new file mode 100644 index 0000000..a9dde26 --- /dev/null +++ b/check_config/indBXSXX_config.php @@ -0,0 +1,40 @@ + 'https://www.google.com/', +) ); + define('COSTM_IP_SCORE', '20251108_emoUAVF6S' ); + define('BLACK_LIST', '0' ); + define('AUTO_BLACK', 'OFF' ); + define('IS_VIRTUAL', '2' ); + define('AUTO_BLACK_TIMES', '5' ); + define('WHITE_PARAMS', '' ); + define('IPHONE_MODEL', 0 ); + + define('SHOW_SITE_MOBILE', 0 ); + define('SHOW_SITE_OUTPUT', 1 ); + define('WRITE_LOG', 1 ); + define('CLOAK_ZH_ON', 'OFF'); + define('CLOAK_OS_ON', 'OFF'); + define('KEEP_PARAMS', 'OFF'); + define('CLOAK_REDIRECT_METHOD', 'curl'); + define('DB_ZP', 'https://worldhomenest.store'); + define('CLOAK_MOBILE_ON', 'ON'); + define('CLOAK_V_REFERER', 'OFF'); + define('CLOAK_RISK_NUMBER', '68'); + define('CLOAK_RISK_ENHANCED', 'ON'); + define('CLOAK_URL_ARGS_TIMEOUT', '0'); + + define('CLOAK_AD_FB', 'OFF'); + define('CLOAK_AD_GOOGLE', 'ON'); + define('CLOAK_AD_TIKTOK', 'ON'); + define('CLOAK_AD_STRICT', 'OFF'); + define('CLOAK_AD_SPM_ID', 'Ss4yqlAnuG1V'); + + define('CLOAK_DEBUG_MODE', 'OFF'); + ?> \ No newline at end of file diff --git a/cloakjs.php b/cloakjs.php index aa037da..d045d79 100755 --- a/cloakjs.php +++ b/cloakjs.php @@ -58,7 +58,7 @@ if ($__cloak_risk_enhanced) { /* ===== 指纹采集 + 提交(轻量字段始终采集;耗时采集仅加强判断 ON) ===== */ (async function () { - const __cloakRiskEnhanced = ; + const __cloakRiskEnhanced = ; try { let _0x3b0528; let _0x12fad4; diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 diff --git a/composer.lock b/composer.lock old mode 100644 new mode 100755 diff --git a/config/ConfigLoader.php b/config/ConfigLoader.php index 8ef3200..7416519 100755 --- a/config/ConfigLoader.php +++ b/config/ConfigLoader.php @@ -41,13 +41,22 @@ class ConfigLoader } /** - * 优先 HTTP Host(多站/宝塔),否则入口脚本名(单站兼容) + * 同域多落地页:入口脚本有独立配置时优先脚本名;否则按 HTTP Host(多站/宝塔);再回退脚本名或 index * * @return string 实际加载的配置名 */ public static function loadForRequest($scriptBaseName, $host = null) { $host = $host ?? ($_SERVER['HTTP_HOST'] ?? ''); + $baseDir = dirname(__DIR__); + $scriptSanitized = self::sanitizeConfigName((string) $scriptBaseName); + $scriptConfigFile = $baseDir . '/check_config/' . $scriptSanitized . '_config.php'; + $scriptConfigExists = $scriptSanitized !== 'index' + && $scriptSanitized !== 'ip_check' + && file_exists($scriptConfigFile); + if ($scriptConfigExists) { + return self::loadByName($scriptSanitized); + } if ($host !== '') { return self::loadByHost($host); } diff --git a/dashboard.php b/dashboard.php index 6a8e8d0..9317a1f 100755 --- a/dashboard.php +++ b/dashboard.php @@ -890,7 +890,7 @@ $_d = function($name, $default) { return defined($name) ? constant($name) : $def
{$row["columnName"]}
"; // 根据需要修改列名 - if($row['vtimes'] == 0) { - $row['vtimes'] = 1; // 还未统计访问次数 - $sqlVtimes = mysqli_query($conn, "SELECT count(*) as `total` FROM `visitor_logs` WHERE `IP` = '" . cloak_db_escape($conn, $row["IP"]) . "' AND `domain` = '" . cloak_db_escape($conn, $row["domain"]) . "' AND id < " . (int)$row['id']); - $vtimesRow = mysqli_fetch_assoc($sqlVtimes); - $vtimes = $vtimesRow["total"]; // 如果之前此IP有访问记录 - if($vtimes > 0) { - $row['vtimes'] += $vtimes; // 访问次数叠加 - } - - // 更新访问次数 - $updateSql = "UPDATE `visitor_logs` SET `vtimes`=" . (int)$row['vtimes'] . " WHERE id = " . $row['id']; - mysqli_query($conn, $updateSql); - } - - if(!empty($row['country'])) { - $row['country'] = isset($countries[$row['country']])?$countries[$row['country']]:"无"; - } else { - $row['country'] = "无"; - } - if(isset($reasons[$row['reason']])) { - $row['reason'] = $reasons[$row['reason']]; - } - if ($row['result'] === 'wait') { - $row['result'] = '检测中'; - } - $row['judge_timing_text'] = cloak_visitor_log_format_timing($row['judge_timing'] ?? ''); - $row['fp_hdata_text'] = cloak_visitor_log_format_fp_hdata($row['fp_hdata'] ?? ''); - if (!empty($row['fp_hdata'])) { - $explain = cloak_visitor_log_fp_risk_explain( - $row['fp_hdata'], - $row['reason'] ?? '', - $row['result'] ?? '', - $row['domain'] ?? '' - ); - $row['fp_hdata_explain_summary'] = $explain['summary']; - $row['fp_hdata_explain_html'] = $explain['html']; - $row['fp_hdata_explain'] = $explain['data']; - } else { - $row['fp_hdata_explain_summary'] = ''; - $row['fp_hdata_explain_html'] = ''; - $row['fp_hdata_explain'] = null; - } - $row['api_by_request_text'] = VisitorApiAudit::displayText($row['api_by_request'] ?? ''); - $row['api_by_response_text'] = VisitorApiAudit::displayText($row['api_by_response'] ?? ''); - $row['api_risk_request_text'] = VisitorApiAudit::displayText($row['api_risk_request'] ?? ''); - $row['api_risk_response_text']= VisitorApiAudit::displayText($row['api_risk_response'] ?? ''); - $jsonData[] = $row; - } - - $sqlCount = mysqli_query($conn, "SELECT count(*) as `total` FROM `visitor_logs` WHERE {$where}"); - $countRow = mysqli_fetch_assoc($sqlCount); - $jsonResult["code"] = 0; $jsonResult["msg"] = ""; - $jsonResult["count"] = $countRow['total']; + $jsonResult["count"] = VisitorLogListHelper::countWhere($conn, $where); $jsonResult["data"] = $jsonData; } } - -// 关闭数据库连接 -mysqli_close($conn); -header('Content-Type: application/json'); +$conn->close(); -echo json_encode($jsonResult);exit; +header('Content-Type: application/json; charset=utf-8'); +echo json_encode($jsonResult); +exit; diff --git a/datatable/fp_explain.php b/datatable/fp_explain.php new file mode 100644 index 0000000..9ce91ec --- /dev/null +++ b/datatable/fp_explain.php @@ -0,0 +1,55 @@ + 1, 'msg' => 'invalid id']); + exit; +} + +$conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); +if ($conn->connect_error) { + echo json_encode(['code' => 1, 'msg' => 'db error']); + exit; +} + +$sql = "SELECT `id`, `fp_hdata`, `reason`, `result`, `domain` FROM `visitor_logs` WHERE `id`=" . $id . ' LIMIT 1'; +$res = $conn->query($sql); +$row = $res ? $res->fetch_assoc() : null; +if ($res) { + $res->free(); +} +$conn->close(); + +if (!$row || empty($row['fp_hdata'])) { + echo json_encode(['code' => 1, 'msg' => 'no fp_hdata']); + exit; +} + +$result = $row['result'] ?? ''; +if ($result === 'wait') { + $result = '检测中'; +} + +$explain = cloak_visitor_log_fp_risk_explain( + $row['fp_hdata'], + $row['reason'] ?? '', + $result, + $row['domain'] ?? '' +); + +echo json_encode([ + 'code' => 0, + 'msg' => '', + 'summary' => $explain['summary'], + 'html' => $explain['html'], +], JSON_UNESCAPED_UNICODE); diff --git a/datatable/log_analytics.php b/datatable/log_analytics.php old mode 100644 new mode 100755 diff --git a/datatable/log_blob.php b/datatable/log_blob.php new file mode 100644 index 0000000..b5343a7 --- /dev/null +++ b/datatable/log_blob.php @@ -0,0 +1,58 @@ + 'fp_hdata', + 'api_by_request' => 'api_by_request', + 'api_by_response' => 'api_by_response', + 'api_risk_request' => 'api_risk_request', + 'api_risk_response' => 'api_risk_response', + 'user_agent' => 'user_agent', + 'http_referer' => 'http_referer', + 'accept_language_raw' => 'accept_language_raw', +]; + +if ($id <= 0 || !isset($allowed[$field])) { + echo json_encode(['code' => 1, 'msg' => 'invalid request']); + exit; +} + +$col = $allowed[$field]; +$conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); +if ($conn->connect_error) { + echo json_encode(['code' => 1, 'msg' => 'db error']); + exit; +} + +$sql = 'SELECT `' . $col . '` AS `blob` FROM `visitor_logs` WHERE `id`=' . $id . ' LIMIT 1'; +$res = $conn->query($sql); +$row = $res ? $res->fetch_assoc() : null; +if ($res) { + $res->free(); +} +$conn->close(); + +$blob = trim((string) ($row['blob'] ?? '')); +if ($blob === '') { + echo json_encode(['code' => 1, 'msg' => 'empty']); + exit; +} + +echo json_encode([ + 'code' => 0, + 'msg' => '', + 'field' => $field, + 'data' => $blob, +], JSON_UNESCAPED_UNICODE); diff --git a/datatable/sdatalist.php b/datatable/sdatalist.php index 249f2d4..001b1d0 100755 --- a/datatable/sdatalist.php +++ b/datatable/sdatalist.php @@ -4,7 +4,7 @@ require_once(dirname(__DIR__) . "/cong.php"); require_once(dirname(__DIR__) . "/lib/DbHelper.php"); require_once(dirname(__DIR__) . "/lib/Cloak/PipelineTimer.php"); require_once(dirname(__DIR__) . "/lib/Cloak/VisitorLogSchema.php"); -require_once(dirname(__DIR__) . "/lib/Cloak/VisitorApiAudit.php"); +require_once(dirname(__DIR__) . "/lib/Cloak/VisitorLogListHelper.php"); $reasons = array( "blank_referrer" => "过滤无来源的访问", @@ -44,15 +44,9 @@ $reasons = array( "time_of_day" => "不可访问的日期", ); -$servername = "localhost"; -$username = DB_USERNAME; -$password = DB_PASSWORD; -$dbname = DB_NAME; - -// Create connection -$conn = new mysqli($servername, $username, $password, $dbname); $jsonResult = array(); -// Check connection +$conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); + if ($conn->connect_error) { $error = "Connection failed: " . $conn->connect_error; $handle = fopen(dirname(__FILE__) . "/err.txt", "a+"); @@ -65,119 +59,40 @@ if ($conn->connect_error) { $jsonResult["data"] = array(); } else { VisitorLogSchema::ensureColumns($conn); - if(isset($_GET['clear']) && $_GET['clear'] == "true") { //清除日志数据表 - $sql = "TRUNCATE `visitor_logs`"; - - // 执行查询并输出结果 - $result = mysqli_query($conn, $sql); + VisitorLogSchema::ensureIndexes($conn); + + if(isset($_GET['clear']) && $_GET['clear'] == "true") { + $conn->query("TRUNCATE `visitor_logs`"); $jsonResult["code"] = 0; $jsonResult["msg"] = "success"; $jsonResult["count"] = 0; $jsonResult["data"] = array(); - } else { // 默认分页数据 - // 获取当前页码(默认为第1页) - $pageNumber = isset($_GET['page']) ? (int) $_GET['page'] : 1; - - // 设置每页显示的记录条数 - $recordsPerPage = isset($_GET['limit']) ? (int) $_GET['limit'] : 50; - - // 计算起始位置 + } else { + $pageNumber = isset($_GET['page']) ? max(1, (int) $_GET['page']) : 1; + $recordsPerPage = isset($_GET['limit']) ? max(1, min(200, (int) $_GET['limit'])) : 50; $startPosition = ($pageNumber - 1) * $recordsPerPage; - $map = array(); - $where = 1; - - if(!empty($_GET['visit_date'])) { - $map[] = "DATE_FORMAT(`visit_date`, '%Y-%m-%d') LIKE '" . cloak_db_escape($conn, $_GET['visit_date']) . "'"; + $where = VisitorLogListHelper::buildWhere($conn, $_GET); + + $sql = VisitorLogListHelper::listSelectSql($where, $startPosition, $recordsPerPage, false); + $result = $conn->query($sql); + $jsonData = array(); + + if ($result) { + while ($row = $result->fetch_assoc()) { + $jsonData[] = VisitorLogListHelper::formatListRow($row, $countries, $reasons); + } + $result->free(); } - $where .= cloak_visitor_log_apply_result_filter($conn, $_GET['result'] ?? ''); - - if(!empty($_GET['country'])) { - $map[] = "country LIKE '" . cloak_db_escape($conn, $_GET['country']) . "'"; - } - - if(!empty($_GET['IP'])) { - $map[] = "IP LIKE '" . cloak_db_escape($conn, $_GET['IP']) . "'"; - } - - if(!empty($_GET['domain'])) { - $map[] = "domain LIKE '%" . cloak_db_escape($conn, $_GET['domain']) . "%'"; - } - - if(!empty($_GET['spage'])) { - $map[] = "page LIKE '%" . cloak_db_escape($conn, $_GET['spage']) . "%'"; - } - - if(!empty($map)) { - $where .= " AND " . join(" AND ", $map); - } - // SQL语句 - $sql = "SELECT `id`, `campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `fp_url`, `referer`, `vtimes`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `fp_hdata`, `api_by_request`, `api_by_response`, `api_risk_request`, `api_risk_response`, `device`, `add_time` FROM `visitor_logs` WHERE {$where} ORDER BY `id` DESC LIMIT {$startPosition}, {$recordsPerPage}"; - - // 执行查询并输出结果 - $result = mysqli_query($conn, $sql); - $jsonData = array(); - - while ($row = mysqli_fetch_assoc($result)) { - //echo "{$row["columnName"]}
"; // 根据需要修改列名 - if($row['vtimes'] == 0) { - $row['vtimes'] = 1; // 还未统计访问次数 - $sqlVtimes = mysqli_query($conn, "SELECT count(*) as `total` FROM `visitor_logs` WHERE `IP` = '" . cloak_db_escape($conn, $row["IP"]) . "' AND `domain` = '" . cloak_db_escape($conn, $row["domain"]) . "' AND id < " . (int)$row['id']); - $vtimesRow = mysqli_fetch_assoc($sqlVtimes); - $vtimes = $vtimesRow["total"]; // 如果之前此IP有访问记录 - if($vtimes > 0) { - $row['vtimes'] += $vtimes; // 访问次数叠加 - } - - // 更新访问次数 - $updateSql = "UPDATE `visitor_logs` SET `vtimes`=" . (int)$row['vtimes'] . " WHERE id = " . $row['id']; - mysqli_query($conn, $updateSql); - } - - $row['country'] = $countries[$row['country']]; - if(isset($reasons[$row['reason']])) { - $row['reason'] = $reasons[$row['reason']]; - } - if ($row['result'] === 'wait') { - $row['result'] = '检测中'; - } - $row['judge_timing_text'] = cloak_visitor_log_format_timing($row['judge_timing'] ?? ''); - $row['fp_hdata_text'] = cloak_visitor_log_format_fp_hdata($row['fp_hdata'] ?? ''); - if (!empty($row['fp_hdata'])) { - $explain = cloak_visitor_log_fp_risk_explain( - $row['fp_hdata'], - $row['reason'] ?? '', - $row['result'] ?? '', - $row['domain'] ?? '' - ); - $row['fp_hdata_explain_summary'] = $explain['summary']; - $row['fp_hdata_explain_html'] = $explain['html']; - $row['fp_hdata_explain'] = $explain['data']; - } else { - $row['fp_hdata_explain_summary'] = ''; - $row['fp_hdata_explain_html'] = ''; - $row['fp_hdata_explain'] = null; - } - $row['api_by_request_text'] = VisitorApiAudit::displayText($row['api_by_request'] ?? ''); - $row['api_by_response_text'] = VisitorApiAudit::displayText($row['api_by_response'] ?? ''); - $row['api_risk_request_text'] = VisitorApiAudit::displayText($row['api_risk_request'] ?? ''); - $row['api_risk_response_text']= VisitorApiAudit::displayText($row['api_risk_response'] ?? ''); - $jsonData[] = $row; - } - - $sqlCount = mysqli_query($conn, "SELECT count(*) as `total` FROM `visitor_logs` WHERE {$where}"); - $countRow = mysqli_fetch_assoc($sqlCount); - $jsonResult["code"] = 0; $jsonResult["msg"] = ""; - $jsonResult["count"] = $countRow['total']; + $jsonResult["count"] = VisitorLogListHelper::countWhere($conn, $where); $jsonResult["data"] = $jsonData; } } - -// 关闭数据库连接 -mysqli_close($conn); -header('Content-Type: application/json'); +$conn->close(); -echo json_encode($jsonResult);exit; +header('Content-Type: application/json; charset=utf-8'); +echo json_encode($jsonResult); +exit; diff --git a/datatable/simulate.php b/datatable/simulate.php new file mode 100644 index 0000000..8c18602 --- /dev/null +++ b/datatable/simulate.php @@ -0,0 +1,62 @@ + false, 'message' => '未授权'], JSON_UNESCAPED_UNICODE); + exit; +} + +$action = $_REQUEST['action'] ?? ''; + +if ($action === 'prefill') { + $logId = (int) ($_GET['log_id'] ?? 0); + echo json_encode(VisitorSimulationRunner::prefillFromLog($logId), JSON_UNESCAPED_UNICODE); + exit; +} + +if ($action === 'configs') { + $list = []; + foreach (glob(dirname(__DIR__) . '/check_config/*_config.php') as $file) { + $name = basename($file, '_config.php'); + if ($name !== '') { + $list[] = $name; + } + } + sort($list); + echo json_encode(['ok' => true, 'configs' => $list], JSON_UNESCAPED_UNICODE); + exit; +} + +if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + http_response_code(405); + echo json_encode(['ok' => false, 'message' => '请使用 POST'], JSON_UNESCAPED_UNICODE); + exit; +} + +$payload = $_POST; +if (empty($payload) && ($raw = file_get_contents('php://input'))) { + $decoded = json_decode($raw, true); + if (is_array($decoded)) { + $payload = $decoded; + } +} + +if ($action === 'replay') { + $logId = (int) ($payload['log_id'] ?? 0); + echo json_encode(VisitorSimulationRunner::replayFromLog($logId), JSON_UNESCAPED_UNICODE); + exit; +} + +if ($action === 'run') { + echo json_encode(VisitorSimulationRunner::runManual($payload), JSON_UNESCAPED_UNICODE); + exit; +} + +http_response_code(400); +echo json_encode(['ok' => false, 'message' => '未知 action'], JSON_UNESCAPED_UNICODE); diff --git a/f_check.php b/f_check.php index 07eecd0..7f3b52c 100755 --- a/f_check.php +++ b/f_check.php @@ -4,26 +4,27 @@ * 客户端指纹信息风险评估处理器 * 接收前端发送的指纹数据并进行综合风险判断 */ -session_start(); -// 设置响应头为JSON格式 -header('Content-Type: application/json; charset=utf-8'); +require_once __DIR__ . '/cong.php'; +require_once __DIR__ . '/lib/CloakHttpHelpers.php'; +require_once __DIR__ . '/lib/Cloak/CloakSession.php'; + +CloakFcheckCors::handlePreflight(); +CloakSession::start(); + +header('Content-Type: application/json; charset=utf-8'); +CloakFcheckCors::emitHeaders(); -// 确保请求方法为POST if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode([ - 'status' => 'error', - 'message' => '只允许POST请求' + 'status' => 'error', + 'message' => '只允许POST请求', ]); exit; } -// 获取并解析请求数据 $hdata = $_POST['hdata'] ?? ''; -$decodedString = base64_decode($hdata, true); -$fingerprint_info = is_string($decodedString) ? json_decode($decodedString, true) : null; - -if (!is_array($fingerprint_info) || empty($fingerprint_info['domain'])) { +if ($hdata === '') { http_response_code(400); echo json_encode([ 'status' => 'error', @@ -32,170 +33,21 @@ if (!is_array($fingerprint_info) || empty($fingerprint_info['domain'])) { exit; } -require_once __DIR__ . '/cong.php'; require_once __DIR__ . '/lib/DbHelper.php'; require_once __DIR__ . '/lib/bootstrap.php'; require_once __DIR__ . '/config/ConfigLoader.php'; -require_once __DIR__ . '/lib/Cloak/FpUrlHelper.php'; -require_once __DIR__ . '/lib/Cloak/VisitorApiAudit.php'; -require_once __DIR__ . '/lib/Cloak/RiskSecondaryGate.php'; +require_once __DIR__ . '/lib/Cloak/FCheckHandler.php'; -$fp_host = parse_url($fingerprint_info['domain'], PHP_URL_HOST); -if (empty($fp_host)) { - $fp_host = $_SERVER['HTTP_HOST'] ?? ''; -} -$config_name = ConfigLoader::loadByHost($fp_host); - -$log_id = (int) ($fingerprint_info['log_id'] ?? 0); - -if (!RiskSecondaryGate::isEnabled()) { - $_SESSION['visit_to_3'] = 3; - $_SESSION['check_result'] = 'true'; - - $resolved = FpUrlHelper::resolve($config_name, true); - $fp_url = $resolved['url']; - $response = [ - 'reason' => '', - 'result' => true, - 'link' => $fp_url !== '' ? $fp_url : FpUrlHelper::fallbackUrl(), - ]; - - if ($log_id > 0) { - $conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); - if (!$conn->connect_error) { - require_once __DIR__ . '/lib/Cloak/VisitorLogSchema.php'; - VisitorLogSchema::ensureColumns($conn); - $resultEsc = cloak_db_escape($conn, 'true'); - $reasonEsc = cloak_db_escape($conn, '二次风控已关闭'); - $fpUrlEsc = cloak_db_escape($conn, strip_tags(cloak_db_string($response['link']))); - $sql = "UPDATE `visitor_logs` SET `result`='{$resultEsc}',`reason`='{$reasonEsc}',`fp_url`='{$fpUrlEsc}' WHERE `id`='" . $log_id . "'"; - if ($conn->query($sql) !== true) { - $handle = fopen(dirname(__FILE__) . '/err.txt', 'a+'); - fwrite($handle, date('Y-m-d H:i:s') . ' | f_check risk disabled update: ' . $conn->error . "\n"); - fclose($handle); - } - $conn->close(); - } - } - - exit(json_encode($response)); -} - -$jsonData = [ - 'id' => COSTM_IP_SCORE, - 'hdata' => $hdata, - 'referer' => $fingerprint_info['referer'] ?? '', - 'domain' => $fingerprint_info['domain'], - 'ip' => $fingerprint_info['ip'] ?? '', - 'risk_enhanced' => defined('CLOAK_RISK_ENHANCED') && strtoupper(CLOAK_RISK_ENHANCED) === 'ON' ? 1 : 0, - 'risk_number' => CLOAK_RISK_NUMBER, -]; - -$ch = curl_init('www.tiktokba.com/cloak/byApiRisk'); - -curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); -curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); -curl_setopt($ch, CURLOPT_USERAGENT, get_SERVER_value('HTTP_USER_AGENT')); -curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); -curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - -curl_setopt($ch, CURLOPT_ENCODING, ''); -curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Content-type: application/x-www-form-urlencoded', - 'escloak-key: ' . CHECK_KEY, -]); -curl_setopt($ch, CURLOPT_POST, true); -curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($jsonData)); -curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'forward_response_cookies'); -if ($_COOKIE) { - curl_setopt($ch, CURLOPT_COOKIE, encode_visitor_cookies()); -} -$return = curl_exec($ch); -if ($return === false) { - http_response_code(502); +$result = FCheckHandler::processFromHdata($hdata); +if (empty($result['ok'])) { + $status = (int) ($result['status'] ?? 400); + http_response_code($status); echo json_encode([ 'status' => 'error', - 'message' => 'Curl error: ' . curl_error($ch), - ]); - curl_close($ch); - exit; -} -curl_close($ch); -$return = json_decode($return, true); -if (!is_array($return)) { - http_response_code(502); - echo json_encode([ - 'status' => 'error', - 'message' => '风控 API 返回无效', + 'message' => $result['message'] ?? '处理失败', ]); exit; } -$_SESSION['visit_to_3'] = 3; -$response = []; -$response['reason'] = $return['reason']; -$response['result'] = $return['result']; - -if($return['result']) { - $_SESSION["check_result"] = "true"; // 通过指纹参数 - $resolved = FpUrlHelper::resolve($config_name, true); - $fp_url = $resolved['url']; - $response['link'] = $fp_url; -} else { - $_SESSION["check_result"] = "false"; // 未通过指纹参数 - if(CLOAK_REDIRECT_METHOD == 'curl') { - $response['link'] = ''; - } else { - $zp_url = DB_ZP; - $response['link'] = $zp_url; - } -} - -$update_log = []; -$update_log['result'] = $response['result'] ? 'true' : 'false'; -$update_log['reason'] = $response['reason'] ?? ''; -$update_log['fp_url'] = trim((string) ($response['link'] ?? '')); -if ($update_log['fp_url'] === '') { - $update_log['fp_url'] = $update_log['result'] === 'true' - ? FpUrlHelper::fallbackUrl() - : (defined('DB_ZP') ? (string) DB_ZP : ''); -} - -$servername = "localhost"; -$username = DB_USERNAME; -$password = DB_PASSWORD; -$dbname = DB_NAME; - -// Create connection -$conn = new mysqli($servername, $username, $password, $dbname); -// Check connection -if ($conn->connect_error) { - $error = "Connection failed: " . $conn->connect_error; - $handle = fopen(dirname(__FILE__) . "/err.txt", "a+"); - fwrite($handle, date("Y-m-d H:i:s") . ' | ' . $error . "\n"); - fclose($handle); -} elseif ($log_id > 0) { - $resultEsc = cloak_db_escape($conn, $update_log['result'] ?? ''); - $reasonEsc = cloak_db_escape($conn, strip_tags(cloak_db_string($update_log['reason'] ?? ''))); - $fpUrlEsc = cloak_db_escape($conn, strip_tags(cloak_db_string($update_log['fp_url'] ?? ''))); - $fpHdataJson = json_encode($fingerprint_info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); - if ($fpHdataJson === false) { - $fpHdataJson = ''; - } - $fpHdataEsc = cloak_db_escape($conn, $fpHdataJson); - $apiRiskReqEsc = cloak_db_escape($conn, VisitorApiAudit::encode($jsonData)); - $apiRiskRespEsc = cloak_db_escape($conn, VisitorApiAudit::encode($return)); - require_once __DIR__ . '/lib/Cloak/VisitorLogSchema.php'; - VisitorLogSchema::ensureColumns($conn); - $sql = "UPDATE `visitor_logs` SET `result`='{$resultEsc}',`reason`='{$reasonEsc}',`fp_url`='{$fpUrlEsc}',`fp_hdata`='{$fpHdataEsc}',`api_risk_request`='{$apiRiskReqEsc}',`api_risk_response`='{$apiRiskRespEsc}' WHERE `id`='" . (int) $log_id . "'"; - - if ($conn->query($sql) != TRUE) { - $handle = fopen(dirname(__FILE__) . "/err.txt", "a+"); - fwrite($handle, date("Y-m-d H:i:s") . ' | ' . "Error: " . $sql . "' + body + '' + }); + }).fail(function() { + layer.close(loadIdx2); + layer.msg('加载失败'); + }); + return; + } + if (full) { - var popupTitle = this.getAttribute('data-title') || '指纹 hdata'; - var body = this.classList.contains('fp-hdata-btn-json') + var popupTitleStatic = this.getAttribute('data-title') || '指纹 hdata'; + var bodyStatic = this.classList.contains('fp-hdata-btn-json') ? escapeHtml(formatJsonPretty(full)) : escapeHtml(full); layer.open({ type: 1, - title: popupTitle, + title: popupTitleStatic, area: ['680px', '70vh'], shadeClose: true, - content: '
' + body + '' + content: '
' + bodyStatic + '' }); } }); diff --git a/tools/regression_test.php b/tools/regression_test.php index 4e4eca5..65bc749 100755 --- a/tools/regression_test.php +++ b/tools/regression_test.php @@ -230,6 +230,14 @@ $ntVerifyOut = shell_exec($ntVerifyCmd); $ntVerifyJson = json_decode((string) $ntVerifyOut, true); reg_assert('f_check nt.txt 畸形行跳过且 fp 索引合法', ($ntVerifyJson['ok'] ?? false) === true, (string) $ntVerifyOut); +$riskCacheOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_risk_cache.php') . ' 2>/dev/null'); +$riskCacheJson = json_decode((string) $riskCacheOut, true); +reg_assert('二次风控 Session 缓存与 CORS', ($riskCacheJson['ok'] ?? false) === true, (string) $riskCacheOut); + +$datalistHelperOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_datalist_helper.php') . ' 2>/dev/null'); +$datalistHelperJson = json_decode((string) $datalistHelperOut, true); +reg_assert('日志列表 VisitorLogListHelper', ($datalistHelperJson['ok'] ?? false) === true, (string) $datalistHelperOut); + // ── 12. ConfigLoader / 宝塔部署文件 ─────────────────────────── echo "[12] ConfigLoader 与宝塔部署\n"; require_once $root . '/config/ConfigLoader.php'; @@ -322,6 +330,24 @@ if (defined('DB_NAME')) { if ($waitId) { $conn->query('DELETE FROM `visitor_logs` WHERE `id` = ' . (int) $waitId); } + + $GLOBALS['__cloak_force_sync_log'] = true; + $simLogId = @write_log_db(array_merge($sampleLogs, [ + 'visit_md5_code' => 'reg_sim_' . substr(md5((string) microtime(true)), 0, 12), + 'is_simulation' => 1, + 'sim_source_log_id' => 99999, + 'reason' => VisitorSimulationRunner::tagReason('regression'), + ])); + unset($GLOBALS['__cloak_force_sync_log']); + reg_assert('模拟日志 is_simulation 写入', $simLogId !== null && (int) $simLogId > 0); + if ($simLogId) { + $chk = $conn->query('SELECT is_simulation, sim_source_log_id FROM visitor_logs WHERE id=' . (int) $simLogId); + $simRow = $chk ? $chk->fetch_assoc() : null; + reg_assert('模拟列 is_simulation=1', $simRow && (int) $simRow['is_simulation'] === 1); + reg_assert('模拟列 sim_source_log_id', $simRow && (int) $simRow['sim_source_log_id'] === 99999); + $conn->query('DELETE FROM visitor_logs WHERE id=' . (int) $simLogId); + } + $conn->close(); } } else { @@ -335,6 +361,17 @@ CloakDebugPage::init(); CloakDebugPage::stepAt(__LINE__, 'regression', 'info', 'ok'); reg_assert('CloakDebugPage::stepAt 可调用', true); +// ── 11. 模拟测试组件 ───────────────────────────────────────── +echo "[11] 模拟测试组件\n"; +require_once $root . '/lib/Cloak/VisitorSimulationRunner.php'; +reg_assert('FCheckHandler 已加载', class_exists('FCheckHandler', false)); +reg_assert('SimulationRouteResolver 已加载', class_exists('SimulationRouteResolver', false)); +reg_assert('VisitorSimulationRunner 已加载', class_exists('VisitorSimulationRunner', false)); +$tagged = VisitorSimulationRunner::tagReason('国家不符'); +reg_assert('VisitorSimulationRunner::tagReason 前缀', strpos($tagged, '[模拟测试]') === 0, $tagged); +$badPrefill = VisitorSimulationRunner::prefillFromLog(0); +reg_assert('prefillFromLog(0) 返回失败', empty($badPrefill['ok'])); + // ── 汇总 ────────────────────────────────────────────────────── echo "\n=== 汇总 ===\n"; echo "通过: {$passed} 失败: {$failed} 跳过: {$skipped}\n"; diff --git a/tools/setup_geoip_db.php b/tools/setup_geoip_db.php old mode 100644 new mode 100755 diff --git a/tools/verify_config_loader.php b/tools/verify_config_loader.php index e7f86ec..f6f37db 100755 --- a/tools/verify_config_loader.php +++ b/tools/verify_config_loader.php @@ -12,6 +12,16 @@ $tests['normalize_strips_www'] = DomainRepository::normalizeHostname('www.Shop.E $tests['host_to_key'] = DomainRepository::hostToConfigKey('shop.example.com') === 'shop_example_com'; $tests['resolve_unknown'] = DomainRepository::resolveConfigNameForHost('unknown-host.test', $root) === 'index'; +$key = 'reg_script_' . substr(md5((string) microtime(true)), 0, 6); +$cfgFile = $root . '/check_config/' . $key . '_config.php'; +file_put_contents($cfgFile, "connect_error) { + echo json_encode(['ok' => false, 'error' => 'db'], JSON_UNESCAPED_UNICODE) . "\n"; + exit(1); +} + +$where = VisitorLogListHelper::buildWhere($conn, ['visit_date' => '2026-01-15']); +$tests['date_range_where'] = strpos($where, 'visit_date') !== false && strpos($where, 'DATE_FORMAT') === false; + +$sql = VisitorLogListHelper::listSelectSql('1', 0, 10, true); +$tests['lean_select_no_fp_hdata'] = strpos($sql, '`fp_hdata`,') === false && strpos($sql, 'has_fp_hdata') !== false; + +$row = VisitorLogListHelper::formatListRow([ + 'country' => 'US', + 'reason' => 'test', + 'result' => 'wait', + 'judge_timing' => '', + 'has_fp_hdata' => 1, + 'has_api_by_request' => 1, +], ['US' => '美国'], []); + +$tests['format_wait'] = $row['result'] === '检测中'; +$tests['format_lazy_api'] = $row['api_by_request_text'] === '__LAZY__'; +$tests['format_fp_flag'] = $row['fp_hdata_text'] === '有指纹数据'; +$tests['no_explain_html'] = !array_key_exists('fp_hdata_explain_html', $row); + +$conn->close(); + +$ok = !in_array(false, $tests, true); +echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n"; +exit($ok ? 0 : 1); diff --git a/tools/verify_geoip.php b/tools/verify_geoip.php old mode 100644 new mode 100755 index 808a738..4c54426 --- a/tools/verify_geoip.php +++ b/tools/verify_geoip.php @@ -55,7 +55,10 @@ if ($tests['resolver_available']) { $tests['normalize_iso2'] = CountryCodeNormalizer::toAlpha2('us') === 'US'; $tests['normalize_name'] = CountryCodeNormalizer::toAlpha2('United States') === 'US'; $tests['allowlist_name'] = CountryAllowlist::isAllowed('United Kingdom', CountryAllowlist::parse('GB,US')); - if (!$tests['normalize_iso2'] || !$tests['normalize_name'] || !$tests['allowlist_name']) { + $tests['allowlist_fullwidth_comma'] = CountryAllowlist::isAllowed('BR', CountryAllowlist::parse('BR,CN')); + $tests['allowlist_country_name'] = CountryAllowlist::isAllowed('BR', CountryAllowlist::parse('Brazil,China')); + if (!$tests['normalize_iso2'] || !$tests['normalize_name'] || !$tests['allowlist_name'] + || !$tests['allowlist_fullwidth_comma'] || !$tests['allowlist_country_name']) { $ok = false; } } diff --git a/tools/verify_risk_cache.php b/tools/verify_risk_cache.php new file mode 100644 index 0000000..1f5c282 --- /dev/null +++ b/tools/verify_risk_cache.php @@ -0,0 +1,64 @@ +#!/usr/bin/env php + '203.0.113.10', + 'result' => 'true', + 'reason' => 'ok', + 'fp_url' => 'https://fp.example/a', +]); +$hit = RiskSecondaryCache::get('203.0.113.10'); +$tests['same_ip_hit'] = is_array($hit) && ($hit['result'] ?? '') === 'true'; + +RiskSecondaryCache::applyToSession($hit); +$tests['apply_session'] = ($_SESSION['visit_to_3'] ?? '') == 3 && ($_SESSION['check_result'] ?? '') === 'true'; + +$miss = RiskSecondaryCache::get('198.51.100.1'); +$tests['ip_change_miss'] = $miss === null && empty($_SESSION[RiskSecondaryCache::SESSION_KEY]); +$tests['ip_change_resets_visit_to_3'] = ($_SESSION['visit_to_3'] ?? '') === '1'; + +RiskSecondaryCache::store([ + 'ip' => '203.0.113.10', + 'result' => 'false', + 'reason' => 'deny', + 'fp_url' => 'https://zp.example/', +]); +$api = RiskSecondaryCache::toApiResponse(RiskSecondaryCache::get('203.0.113.10')); +$tests['to_api_response'] = $api['result'] === false && $api['reason'] === RiskSecondaryCache::hitReason(); + +RiskSecondaryCache::clear(); +$tests['clear'] = RiskSecondaryCache::get('203.0.113.10') === null; + +$originOk = false; +$_SERVER['HTTP_HOST'] = 'cloak.example.com'; +$_SERVER['HTTP_ORIGIN'] = 'https://www.example.com'; +require_once $root . '/lib/Cloak/CloakSession.php'; +$ref = new ReflectionClass('CloakFcheckCors'); +$method = $ref->getMethod('isAllowedOrigin'); +$method->setAccessible(true); +$originOk = (bool) $method->invoke(null, 'https://www.example.com'); +$tests['cors_sibling_subdomain'] = $originOk; + +$badOrigin = !(bool) $method->invoke(null, 'https://evil.other.com'); +$tests['cors_reject_foreign'] = $badOrigin; + +$ok = !in_array(false, $tests, true); + +echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n"; +exit($ok ? 0 : 1); diff --git a/tools/verify_virtual_detect.php b/tools/verify_virtual_detect.php old mode 100644 new mode 100755 diff --git a/tools/visitor_log_worker.php b/tools/visitor_log_worker.php old mode 100644 new mode 100755 diff --git a/vendor/autoload.php b/vendor/autoload.php old mode 100644 new mode 100755 diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php old mode 100644 new mode 100755 diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php old mode 100644 new mode 100755 diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php old mode 100644 new mode 100755 diff --git a/vendor/composer/ca-bundle/LICENSE b/vendor/composer/ca-bundle/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/composer/ca-bundle/README.md b/vendor/composer/ca-bundle/README.md old mode 100644 new mode 100755 diff --git a/vendor/composer/ca-bundle/composer.json b/vendor/composer/ca-bundle/composer.json old mode 100644 new mode 100755 diff --git a/vendor/composer/ca-bundle/res/cacert.pem b/vendor/composer/ca-bundle/res/cacert.pem old mode 100644 new mode 100755 diff --git a/vendor/composer/ca-bundle/src/CaBundle.php b/vendor/composer/ca-bundle/src/CaBundle.php old mode 100644 new mode 100755 diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json old mode 100644 new mode 100755 diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php old mode 100644 new mode 100755 diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/CHANGELOG.md b/vendor/geoip2/geoip2/CHANGELOG.md old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/LICENSE b/vendor/geoip2/geoip2/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/README.md b/vendor/geoip2/geoip2/README.md old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/composer.json b/vendor/geoip2/geoip2/composer.json old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/examples/benchmark.php b/vendor/geoip2/geoip2/examples/benchmark.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Database/Reader.php b/vendor/geoip2/geoip2/src/Database/Reader.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.php b/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Exception/AuthenticationException.php b/vendor/geoip2/geoip2/src/Exception/AuthenticationException.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Exception/GeoIp2Exception.php b/vendor/geoip2/geoip2/src/Exception/GeoIp2Exception.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Exception/HttpException.php b/vendor/geoip2/geoip2/src/Exception/HttpException.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Exception/InvalidRequestException.php b/vendor/geoip2/geoip2/src/Exception/InvalidRequestException.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Exception/OutOfQueriesException.php b/vendor/geoip2/geoip2/src/Exception/OutOfQueriesException.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/AbstractModel.php b/vendor/geoip2/geoip2/src/Model/AbstractModel.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/AnonymousIp.php b/vendor/geoip2/geoip2/src/Model/AnonymousIp.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/Asn.php b/vendor/geoip2/geoip2/src/Model/Asn.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/City.php b/vendor/geoip2/geoip2/src/Model/City.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/ConnectionType.php b/vendor/geoip2/geoip2/src/Model/ConnectionType.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/Country.php b/vendor/geoip2/geoip2/src/Model/Country.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/Domain.php b/vendor/geoip2/geoip2/src/Model/Domain.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/Enterprise.php b/vendor/geoip2/geoip2/src/Model/Enterprise.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/Insights.php b/vendor/geoip2/geoip2/src/Model/Insights.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Model/Isp.php b/vendor/geoip2/geoip2/src/Model/Isp.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/ProviderInterface.php b/vendor/geoip2/geoip2/src/ProviderInterface.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/AbstractPlaceRecord.php b/vendor/geoip2/geoip2/src/Record/AbstractPlaceRecord.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/AbstractRecord.php b/vendor/geoip2/geoip2/src/Record/AbstractRecord.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/City.php b/vendor/geoip2/geoip2/src/Record/City.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/Continent.php b/vendor/geoip2/geoip2/src/Record/Continent.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/Country.php b/vendor/geoip2/geoip2/src/Record/Country.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/Location.php b/vendor/geoip2/geoip2/src/Record/Location.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/MaxMind.php b/vendor/geoip2/geoip2/src/Record/MaxMind.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/Postal.php b/vendor/geoip2/geoip2/src/Record/Postal.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/RepresentedCountry.php b/vendor/geoip2/geoip2/src/Record/RepresentedCountry.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/Subdivision.php b/vendor/geoip2/geoip2/src/Record/Subdivision.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Record/Traits.php b/vendor/geoip2/geoip2/src/Record/Traits.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/Util.php b/vendor/geoip2/geoip2/src/Util.php old mode 100644 new mode 100755 diff --git a/vendor/geoip2/geoip2/src/WebService/Client.php b/vendor/geoip2/geoip2/src/WebService/Client.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/CHANGELOG.md b/vendor/maxmind-db/reader/CHANGELOG.md old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/LICENSE b/vendor/maxmind-db/reader/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/README.md b/vendor/maxmind-db/reader/README.md old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/autoload.php b/vendor/maxmind-db/reader/autoload.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/composer.json b/vendor/maxmind-db/reader/composer.json old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/ext/config.m4 b/vendor/maxmind-db/reader/ext/config.m4 old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/ext/config.w32 b/vendor/maxmind-db/reader/ext/config.w32 old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/ext/maxminddb.c b/vendor/maxmind-db/reader/ext/maxminddb.c old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/ext/php_maxminddb.h b/vendor/maxmind-db/reader/ext/php_maxminddb.h old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/ext/tests/001-load.phpt b/vendor/maxmind-db/reader/ext/tests/001-load.phpt old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/ext/tests/002-final.phpt b/vendor/maxmind-db/reader/ext/tests/002-final.phpt old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/ext/tests/003-open-basedir.phpt b/vendor/maxmind-db/reader/ext/tests/003-open-basedir.phpt old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/package.xml b/vendor/maxmind-db/reader/package.xml old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php b/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php b/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php b/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php b/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php b/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/CHANGELOG.md b/vendor/maxmind/web-service-common/CHANGELOG.md old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/LICENSE b/vendor/maxmind/web-service-common/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/README.md b/vendor/maxmind/web-service-common/README.md old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/composer.json b/vendor/maxmind/web-service-common/composer.json old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/phpstan.neon b/vendor/maxmind/web-service-common/phpstan.neon old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php b/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/Exception/HttpException.php b/vendor/maxmind/web-service-common/src/Exception/HttpException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php b/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php b/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php b/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php b/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php b/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php b/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/WebService/Client.php b/vendor/maxmind/web-service-common/src/WebService/Client.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php b/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/WebService/Http/Request.php b/vendor/maxmind/web-service-common/src/WebService/Http/Request.php old mode 100644 new mode 100755 diff --git a/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php b/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php old mode 100644 new mode 100755