Files
wevads-platform/public/tracking-deploy.php

438 lines
19 KiB
PHP

<?php
/**
* WEVAL Tracking Deployment Manager v3.1
* + Domain Warming System
*/
session_start();
$tracking_ip = '151.80.235.110';
$wevads_ip = '89.167.40.150';
// Warming thresholds
define('SCORE_ACTIVE', 70); // >= 70 = Active
define('SCORE_WARMING', 50); // 50-69 = Warming
// < 50 = Restricted
function checkDomainReputation($domain) {
$tldScores = [
'com' => 95, 'net' => 90, 'org' => 90, 'io' => 75, 'co' => 75,
'de' => 85, 'fr' => 85, 'uk' => 85, 'eu' => 80,
'info' => 60, 'biz' => 55, 'charity' => 45, 'site' => 40,
'xyz' => 40, 'top' => 35, 'click' => 30
];
$parts = explode('.', $domain);
$tld = strtolower(end($parts));
$score = $tldScores[$tld] ?? 50;
// Blacklist check
$blacklists = ['zen.spamhaus.org', 'bl.spamcop.net'];
$blHits = 0;
foreach ($blacklists as $bl) {
if (@dns_get_record("$domain.$bl", DNS_A)) {
$score -= 15;
$blHits++;
}
}
// DNS bonus
if (@dns_get_record($domain, DNS_A)) $score += 3;
if (@dns_get_record($domain, DNS_MX)) $score += 2;
$score = max(0, min(100, $score));
// Determine status
if ($score >= SCORE_ACTIVE) {
$status = 'active';
$statusLabel = 'ACTIVE';
$statusColor = '#10b981';
$recommendation = 'Ready for full volume sending';
$maxDaily = 'Unlimited';
} elseif ($score >= SCORE_WARMING) {
$status = 'warming';
$statusLabel = 'WARMING';
$statusColor = '#f59e0b';
$recommendation = 'Use progressive volume: Start 100/day, increase 20% daily';
$maxDaily = 'Start 100, +20%/day';
} else {
$status = 'restricted';
$statusLabel = 'RESTRICTED';
$statusColor = '#ef4444';
$recommendation = 'Not recommended. Use only as backup or acquire better domain.';
$maxDaily = 'Backup only';
}
$rating = $score >= 80 ? 'Excellent' : ($score >= 60 ? 'Good' : ($score >= 40 ? 'Fair' : 'Poor'));
return [
'score' => $score,
'rating' => $rating,
'tld' => ".$tld",
'status' => $status,
'statusLabel' => $statusLabel,
'statusColor' => $statusColor,
'recommendation' => $recommendation,
'maxDaily' => $maxDaily,
'blacklistHits' => $blHits,
'warmingPlan' => $status === 'warming' ? [
'day1' => 100,
'day2' => 120,
'day3' => 144,
'day4' => 173,
'day5' => 207,
'day6' => 249,
'day7' => 299,
'day14' => 743,
'day21' => 1847,
'day30' => 5765
] : null
];
}
function testServer($ip) {
$fp = @fsockopen($ip, 80, $errno, $errstr, 5);
if ($fp) { fclose($fp); return ['status' => 'online']; }
return ['status' => 'offline', 'error' => $errstr];
}
// Handle AJAX
if (isset($_REQUEST['action'])) {
header('Content-Type: application/json');
switch ($_REQUEST['action']) {
case 'test':
echo json_encode(testServer($_POST['ip'] ?? '151.80.235.110'));
break;
case 'check_domain':
echo json_encode(checkDomainReputation($_POST['domain'] ?? ''));
break;
case 'deploy':
$ip = $_POST['ip'] ?? '';
$pass = $_POST['password'] ?? '';
$domain = $_POST['domain'] ?? $ip;
if (!$ip || !$pass) {
echo json_encode(['success' => false, 'message' => 'IP and password required']);
break;
}
$script = '#!/bin/bash
set -e
apt-get update -qq
apt-get install -y -qq nginx php-fpm
mkdir -p /var/www/tracking/{c,o,u} /var/log/tracking
cat > /var/www/tracking/c/index.php << "INNEREOF"
<?php
header("X-Robots-Tag: noindex");
$d = explode("/", trim($_SERVER["REQUEST_URI"], "/"))[1] ?? "";
@file_put_contents("/var/log/tracking/clicks.log", date("Y-m-d H:i:s")." | ".$_SERVER["REMOTE_ADDR"]." | $d\n", FILE_APPEND);
$ctx = stream_context_create(["http" => ["timeout" => 3]]);
$r = @file_get_contents("http://'.$wevads_ip.':5821/api/track/click?data=".urlencode($d), false, $ctx);
$j = @json_decode($r, true);
if (isset($j["redirect"])) { header("Location: ".$j["redirect"], true, 302); exit; }
header("Content-Type: image/gif");
echo base64_decode("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
INNEREOF
cat > /var/www/tracking/o/index.php << "INNEREOF"
<?php
header("X-Robots-Tag: noindex");
header("Cache-Control: no-cache");
$d = explode("/", trim($_SERVER["REQUEST_URI"], "/"))[1] ?? "";
@file_put_contents("/var/log/tracking/opens.log", date("Y-m-d H:i:s")." | ".$_SERVER["REMOTE_ADDR"]." | $d\n", FILE_APPEND);
@file_get_contents("http://'.$wevads_ip.':5821/api/track/open?data=".urlencode($d), false, stream_context_create(["http"=>["timeout"=>1]]));
header("Content-Type: image/gif");
echo base64_decode("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
INNEREOF
cat > /var/www/tracking/u/index.php << "INNEREOF"
<?php
$d = explode("/", trim($_SERVER["REQUEST_URI"], "/"))[1] ?? "";
@file_put_contents("/var/log/tracking/unsubs.log", date("Y-m-d H:i:s")." | ".$_SERVER["REMOTE_ADDR"]." | $d\n", FILE_APPEND);
header("Location: http://'.$wevads_ip.':5821/unsubscribe?d=".urlencode($d));
INNEREOF
PHP_VER=$(php -r "echo PHP_MAJOR_VERSION.\".\".PHP_MINOR_VERSION;")
cat > /etc/nginx/sites-available/tracking << NGINXEOF
server {
listen 80;
server_name '.$domain.' _;
root /var/www/tracking;
location /c/ { try_files \\\$uri /c/index.php; }
location /o/ { try_files \\\$uri /o/index.php; }
location /u/ { try_files \\\$uri /u/index.php; }
location ~ \\.php\\\$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php\${PHP_VER}-fpm.sock;
}
}
NGINXEOF
ln -sf /etc/nginx/sites-available/tracking /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
chown -R www-data:www-data /var/www/tracking /var/log/tracking
nginx -t && systemctl restart nginx php*-fpm
echo "DEPLOY_SUCCESS"';
$tmpFile = '/tmp/deploy_' . md5($ip) . '.sh';
file_put_contents($tmpFile, $script);
$cmd = "sshpass -p " . escapeshellarg($pass) . " ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@$ip 'bash -s' < $tmpFile 2>&1";
$output = shell_exec($cmd);
@unlink($tmpFile);
echo json_encode([
'success' => strpos($output, 'DEPLOY_SUCCESS') !== false,
'output' => $output
]);
break;
}
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>WEVAL | Tracking Deployment</title>
<link href="plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="plugins/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<style>
body { background: #0a0e17; color: #f1f5f9; font-family: 'Segoe UI', sans-serif; }
.container-main { max-width: 1300px; margin: 30px auto; padding: 20px; }
.card-dark { background: #1a2332; border: 1px solid #2a3a50; border-radius: 12px; margin-bottom: 20px; }
.card-dark .card-header { background: #111827; border-bottom: 1px solid #2a3a50; padding: 15px 20px; font-weight: 600; }
.card-dark .card-body { padding: 20px; }
.form-control-dark { background: #0d1219; border: 1px solid #2a3a50; color: #fff; border-radius: 8px; padding: 10px 15px; width: 100%; }
.form-control-dark:focus { border-color: #00e5ff; outline: none; background: #0d1219; color: #fff; }
.btn-cyber { padding: 10px 20px; border-radius: 8px; font-weight: 600; border: none; cursor: pointer; transition: all 0.2s; }
.btn-cyber:hover { transform: translateY(-2px); }
.btn-primary-cyber { background: linear-gradient(135deg, #00e5ff, #0891b2); color: #000; }
.btn-success-cyber { background: linear-gradient(135deg, #10b981, #059669); color: #fff; }
.status-badge { padding: 8px 16px; border-radius: 20px; font-weight: 600; font-size: 14px; display: inline-block; }
.status-active { background: rgba(16,185,129,0.2); color: #10b981; border: 1px solid #10b981; }
.status-warming { background: rgba(245,158,11,0.2); color: #f59e0b; border: 1px solid #f59e0b; }
.status-restricted { background: rgba(239,68,68,0.2); color: #ef4444; border: 1px solid #ef4444; }
.status-online { color: #10b981; }
.status-offline { color: #ef4444; }
.score-box { font-size: 56px; font-weight: 700; font-family: 'Courier New', monospace; }
.info-box { background: rgba(0,229,255,0.1); border: 1px solid rgba(0,229,255,0.3); border-radius: 8px; padding: 15px; margin-bottom: 20px; }
.warning-box { background: rgba(245,158,11,0.1); border: 1px solid rgba(245,158,11,0.3); border-radius: 8px; padding: 15px; }
.log-box { background: #0d1219; border: 1px solid #2a3a50; border-radius: 8px; padding: 15px; font-family: monospace; font-size: 13px; max-height: 250px; overflow-y: auto; }
h1 { color: #00e5ff; margin-bottom: 5px; }
label { color: #94a3b8; font-size: 13px; margin-bottom: 5px; display: block; }
.rule-box { background: #111827; border-radius: 8px; padding: 15px; margin-top: 15px; }
.rule-item { display: flex; align-items: center; padding: 8px 0; border-bottom: 1px solid #2a3a50; }
.rule-item:last-child { border-bottom: none; }
.rule-score { width: 100px; font-weight: 600; }
.rule-status { width: 120px; }
.rule-action { flex: 1; color: #94a3b8; font-size: 13px; }
.warming-plan { margin-top: 15px; }
.warming-plan table { width: 100%; font-size: 13px; }
.warming-plan th { color: #64748b; font-weight: 500; padding: 8px; text-align: left; }
.warming-plan td { padding: 8px; border-top: 1px solid #2a3a50; }
.form-group { margin-bottom: 15px; }
</style>
</head>
<body>
<div class="container-main">
<h1><i class="fa fa-rocket"></i> Tracking Server Deployment</h1>
<p style="color:#64748b;margin-bottom:25px;">Deploy tracking servers and manage domain warming for optimal deliverability</p>
<!-- Current Status -->
<div class="card-dark">
<div class="card-header"><i class="fa fa-server"></i> Current Tracking Server</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label>IP Address</label>
<div style="font-size:24px;font-family:monospace;"><?= $tracking_ip ?></div>
</div>
<div class="col-md-3">
<label>Status</label>
<div id="current-status"><i class="fa fa-spinner fa-spin"></i> Checking...</div>
</div>
<div class="col-md-3">
<label>Domain</label>
<div style="color:#f59e0b;">No domain configured</div>
</div>
<div class="col-md-3">
<label>Action</label>
<button class="btn btn-cyber btn-primary-cyber btn-sm" onclick="testCurrent()">
<i class="fa fa-refresh"></i> Refresh
</button>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Deploy Section -->
<div class="col-md-6">
<div class="card-dark">
<div class="card-header"><i class="fa fa-cloud-upload"></i> Deploy to New Server</div>
<div class="card-body">
<div class="form-group">
<label>New Server IP</label>
<input type="text" class="form-control-dark" id="new-ip" placeholder="e.g., 5.161.xxx.xxx">
</div>
<div class="form-group">
<label>Root Password</label>
<input type="password" class="form-control-dark" id="new-pass" placeholder="SSH password">
</div>
<div class="form-group">
<label>Domain (optional)</label>
<input type="text" class="form-control-dark" id="new-domain" placeholder="track.example.com">
</div>
<button class="btn btn-cyber btn-primary-cyber" onclick="deployServer()">
<i class="fa fa-rocket"></i> Deploy Tracking
</button>
<div class="log-box mt-3" id="deploy-log" style="display:none;"></div>
</div>
</div>
</div>
<!-- Domain Checker -->
<div class="col-md-6">
<div class="card-dark">
<div class="card-header"><i class="fa fa-shield"></i> Domain Reputation & Warming</div>
<div class="card-body">
<div class="form-group">
<label>Check Domain</label>
<div class="input-group" style="display:flex;gap:10px;">
<input type="text" class="form-control-dark" id="check-domain" placeholder="example.com" style="flex:1;">
<button class="btn btn-cyber btn-success-cyber" onclick="checkDomain()">
<i class="fa fa-search"></i> Check
</button>
</div>
</div>
<div id="domain-result" style="display:none;">
<div style="display:flex;align-items:center;gap:20px;margin:20px 0;">
<div class="score-box" id="domain-score">--</div>
<div>
<div id="domain-status-badge" class="status-badge">--</div>
<div style="color:#64748b;margin-top:5px;font-size:13px;" id="domain-tld"></div>
</div>
</div>
<div class="warning-box" id="domain-recommendation"></div>
<div id="warming-plan-box" style="display:none;">
<div class="warming-plan">
<h6 style="color:#f59e0b;margin-top:15px;"><i class="fa fa-fire"></i> Warming Schedule</h6>
<table>
<tr><th>Day</th><th>Max Emails</th><th>Day</th><th>Max Emails</th></tr>
<tr><td>Day 1</td><td id="wp-d1">100</td><td>Day 7</td><td id="wp-d7">299</td></tr>
<tr><td>Day 3</td><td id="wp-d3">144</td><td>Day 14</td><td id="wp-d14">743</td></tr>
<tr><td>Day 5</td><td id="wp-d5">207</td><td>Day 30</td><td id="wp-d30">5,765</td></tr>
</table>
</div>
</div>
</div>
<!-- Rules Reference -->
<div class="rule-box">
<h6 style="color:#00e5ff;margin-bottom:10px;"><i class="fa fa-list-ul"></i> Warming Rules</h6>
<div class="rule-item">
<div class="rule-score" style="color:#10b981;">≥ 70</div>
<div class="rule-status"><span class="status-badge status-active">ACTIVE</span></div>
<div class="rule-action">Full volume, no restrictions</div>
</div>
<div class="rule-item">
<div class="rule-score" style="color:#f59e0b;">50-69</div>
<div class="rule-status"><span class="status-badge status-warming">WARMING</span></div>
<div class="rule-action">Progressive: 100/day +20%</div>
</div>
<div class="rule-item">
<div class="rule-score" style="color:#ef4444;">&lt; 50</div>
<div class="rule-status"><span class="status-badge status-restricted">RESTRICTED</span></div>
<div class="rule-action">Backup only, acquire better domain</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="plugins/jquery.min.js"></script>
<script>
function testCurrent() {
$('#current-status').html('<i class="fa fa-spinner fa-spin"></i> Checking...');
$.post('?action=test', {ip: '<?= $tracking_ip ?>'}, function(r) {
$('#current-status').html(r.status === 'online'
? '<span class="status-online"><i class="fa fa-check-circle"></i> Online</span>'
: '<span class="status-offline"><i class="fa fa-times-circle"></i> Offline</span>');
});
}
function checkDomain() {
var domain = $('#check-domain').val().trim();
if (!domain) return alert('Enter a domain');
$('#domain-score').text('...');
$('#domain-result').show();
$.post('?action=check_domain', {domain: domain}, function(r) {
// Score color
var scoreColor = r.score >= 70 ? '#10b981' : (r.score >= 50 ? '#f59e0b' : '#ef4444');
$('#domain-score').text(r.score).css('color', scoreColor);
// Status badge
$('#domain-status-badge')
.text(r.statusLabel)
.removeClass('status-active status-warming status-restricted')
.addClass('status-' + r.status);
$('#domain-tld').text('TLD: ' + r.tld + ' | Rating: ' + r.rating);
$('#domain-recommendation').html('<strong>Recommendation:</strong> ' + r.recommendation + '<br><strong>Max Daily:</strong> ' + r.maxDaily);
// Show warming plan if needed
if (r.status === 'warming' && r.warmingPlan) {
$('#wp-d1').text(r.warmingPlan.day1);
$('#wp-d3').text(r.warmingPlan.day3);
$('#wp-d5').text(r.warmingPlan.day5);
$('#wp-d7').text(r.warmingPlan.day7);
$('#wp-d14').text(r.warmingPlan.day14);
$('#wp-d30').text(r.warmingPlan.day30.toLocaleString());
$('#warming-plan-box').show();
} else {
$('#warming-plan-box').hide();
}
});
}
function deployServer() {
var ip = $('#new-ip').val().trim();
var pass = $('#new-pass').val();
var domain = $('#new-domain').val().trim();
if (!ip || !pass) return alert('IP and password required');
$('#deploy-log').show().html('<i class="fa fa-spinner fa-spin"></i> Connecting to ' + ip + '...');
$.post('?action=deploy', {ip: ip, password: pass, domain: domain || ip}, function(r) {
if (r.success) {
$('#deploy-log').html('<span style="color:#10b981;"><i class="fa fa-check"></i> Deployment successful!</span><br><br>Tracking ready at:<br>http://' + (domain || ip) + '/c/{data}<br>http://' + (domain || ip) + '/o/{data}');
} else {
$('#deploy-log').html('<span style="color:#ef4444;"><i class="fa fa-times"></i> Deployment failed</span><br><pre style="color:#94a3b8;font-size:11px;white-space:pre-wrap;">' + (r.output || r.message) + '</pre>');
}
}).fail(function() {
$('#deploy-log').html('<span style="color:#ef4444;">Connection error</span>');
});
}
$(document).ready(function() {
testCurrent();
// Auto-check culturellemejean.charity
$('#check-domain').val('culturellemejean.charity');
checkDomain();
});
</script>
</body>
</html>