Hide the admin security code
[elbandi:minifaucet.git] / index.php
1 <?php
2
3 require 'core.php';
4
5 session_start();
6
7 \Slim\Slim::registerAutoloader();
8
9 $app = new \Slim\Slim();
10
11 $checkaddress = function ($app, $need = true) {
12     return function () use ($app, $need) {
13         if ($need) {
14             if (empty($_SESSION['address'])) {
15                 $app->redirect($app->urlFor('root'));
16             }
17         } else {
18             if (!empty($_SESSION['address'])) {
19                 $app->redirect($app->urlFor('faucet'));
20             }
21         }
22     };
23 };
24
25 $checkclaim = function ($app) {
26     return function () use ($app) {
27         global $dispenseTime, $recaptchaPub;
28         $address = $_SESSION['address'];
29         $ip = getIP();
30         $sql = "SELECT dispensed FROM dispenses WHERE email='$address' OR ip='$ip' ";
31         $sql .= "ORDER BY id DESC LIMIT 1";
32         $lastclaim_query = sql_query($sql);
33         $canclaim = true;
34
35         if ($lastclaim_query->num_rows) {
36             $lastclaim = fetch_one($lastclaim_query);
37             $lastclaim = strtotime($lastclaim);
38             if ($lastclaim + $dispenseTime > time()) {
39                 $canclaim = false;
40                 $app->view()->setData('nextclaim', relative_time($lastclaim + $dispenseTime));
41             }
42         }
43
44         $app->view()->setData('canclaim', $canclaim);
45         if ($canclaim) {
46             $app->view()->setData('recaptcha', recaptcha_get_html($recaptchaPub));
47         }
48     };
49 };
50
51 $app->hook('slim.before.dispatch', function () use ($app) {
52     global $siteName, $squareAds, $textAds, $bannerAds, $rewards, $links;
53     global $cashout;
54     $address = null;
55     if (isset($_SESSION['address'])) {
56         $address = $_SESSION['address'];
57     }
58
59     $flash = $app->view()->getData('flash');
60
61     $error = '';
62     if (isset($flash['error'])) {
63         $error = $flash['error'];
64     }
65     $success = '';
66     if (isset($flash['success'])) {
67         $success = $flash['success'];
68     }
69
70     $app->view()->setData('success', $success);
71     $app->view()->setData('error', $error);
72     $app->view()->setData('address', $address);
73     $app->view()->setData('siteName', $siteName);
74     $app->view()->setData('squareAds', $squareAds);
75     $app->view()->setData('textAds', $textAds);
76     $app->view()->setData('bannerAds', $bannerAds);
77     $app->view()->setData('rewards', $rewards);
78     $app->view()->setData('links', $links);
79     $app->view()->setData('cashout', $cashout);
80     $app->view()->setData('isAdmin', false);
81 });
82
83 $app->get("/", $checkaddress($app, false), function () use ($app) {
84     global $minReward, $maxReward, $dispenseTimeText, $apiKey, $guid;
85     global $allowEmail, $allowCoin;
86     $id = $app->request()->get('id');
87     if (!is_null($id) && is_numeric($id)) {
88         $_SESSION['referer'] = $id;
89     }
90
91     if (!empty($apiKey)) {
92         $app->view()->setData('wallet', "<a href='https://coinbase.com'>Powered by Coinbase</a>");
93     } elseif (!empty($guid)) {
94         $app->view()->setData('wallet', "<a href='https://blockchain.info'>Powered by Blockchain.info</a>");
95     }
96
97     $addr = array();
98     if ($allowCoin) {
99         $addr[] = COIN_NAME;
100     }
101     if ($allowEmail) {
102         $addr[] = "email";
103     }
104     $app->view()->setData('addressType', implode("/", $addr));
105     $app->view()->setData('minReward', $minReward);
106     $app->view()->setData('maxReward', $maxReward);
107     $app->view()->setData('dispenseTimeText', $dispenseTimeText);
108     $app->render('main.php', array('title' => 'Home'));
109 })->name('root');
110
111 $app->get("/about", function () use ($app) {
112     $app->render('about.php', array('title' => 'About'));
113 })->name('about');
114
115 $checkadmin = function ($app) {
116     return function () use ($app) {
117         $app->view()->setData('isAdmin', isset($_SESSION['isadmin']) ? $_SESSION['isadmin'] : false);
118     };
119 };
120
121 $app->get("/admin(/:cmd)", $checkadmin($app), function ($cmd = null) use ($app) {
122     global $recaptchaPub, $fee;
123
124 /*
125     if (($cmdget = $app->request()->get('cmd')) != null) {
126         $cmd = $cmdget;
127     }
128 */
129     $flash = $app->view()->getData('flash');
130     $isadmin = $app->view()->getData('isAdmin');
131     switch ($cmd) {
132         default:
133 defaultlabel:
134             if (!isset($_SESSION['isadmin'])) {
135                 $app->view()->setData('recaptcha', recaptcha_get_html($recaptchaPub));
136             }
137
138             $sql = "SELECT COUNT(*) AS num_addresses, MAX(balance) AS max_balance, SUM(balance) as sum_balance, ";
139             $sql .= "MAX(totalbalance) as max_totalbalance, SUM(totalbalance) as sum_totalbalance ";
140             $sql .= "FROM balances WHERE email <> 'SERVERBALANCE'";
141             $stat_query = sql_query($sql);
142             $statBalance = fetch_assoc($stat_query);
143
144             $app->view()->setData('statBalance', $statBalance);
145             $app->view()->setData('serverbalance', number_format(getserverbalance()));
146             $app->render('admin.php', array('title' => 'Admin'));
147     }
148 })->name('admin');
149
150 $app->post("/admin", $checkadmin($app), function () use ($app) {
151     global $adminSeccode, $recaptchaPrv;
152     $isadmin = $app->view()->getData('isAdmin');
153     $cmd = $app->request()->post('cmd');
154     switch ($cmd) {
155         case "updatebalance":
156             if (!$isadmin) {
157                 goto defaultlabel;
158             }
159             $balance = getserverbalance(true);
160             if ($balance > 0) {
161                 $app->flash('success', "Balance is updated");
162             } else {
163                 $app->flash('error', "Balance is not updated or balance is empty");
164             }
165             break;
166         case "logout":
167             unset($_SESSION['isadmin']);
168             break;
169         case "login":
170             $seccode = $app->request()->post('seccode');
171             if (!empty($adminSeccode) && $seccode === $adminSeccode) {
172                 $resp = recaptcha_check_answer($recaptchaPrv, getIP(),
173                     $app->request()->post('recaptcha_challenge_field'), $app->request()->post('recaptcha_response_field'));
174                 if ($resp->is_valid) {
175                     $_SESSION['isadmin'] = true;
176                 } else {
177                     $app->flash('error', "CAPTCHA incorrect. Please try again.");
178                 }
179             } else {
180                 $app->flash('error', "Invalid security code.");
181             }
182             break;
183         default:
184 defaultlabel:
185             break;
186     }
187     $app->redirect($app->urlFor('admin'));
188 })->name('post_admin');
189
190 $app->get("/faucet", $checkaddress($app, true), $checkclaim($app), function () use ($app) {
191     global $referPercent, $forcewait;
192     $flash = $app->view()->getData('flash');
193     $address = $app->view()->getData('address');
194
195     $amount = null;
196     if (isset($flash['amount'])) {
197         $amount = $flash['amount'];
198     }
199     $sentamount = null;
200     if (isset($flash['sentamount'])) {
201         $sentamount = $flash['sentamount'];
202     }
203
204     $query_balance = sql_query("SELECT * FROM balances WHERE email='$address'");
205     if ($query_balance->num_rows) {
206         $balance = $query_balance->fetch_assoc();
207     } else {
208         $balance = array('balance' => 0, 'totalbalance' => 0, 'id' => 0);
209     }
210
211     $app->view()->setData('balance_current', $balance["balance"]);
212     $app->view()->setData('balance_alltime', $balance["totalbalance"]);
213     $reflink = "http://" . $_SERVER['SERVER_NAME'] . $app->urlFor('root') . "?id=" . $balance["id"];
214     $app->view()->setData('reflink', $reflink);
215     $app->view()->setData('serverbalance', number_format(getserverbalance()));
216     $app->view()->setData('forcewait', $forcewait);
217     $app->view()->setData('referPercent', $referPercent);
218
219     $app->view()->setData('amount', $amount);
220     $app->view()->setData('sentamount', $sentamount);
221     $app->render('faucet.php', array('title' => 'Faucet'));
222 })->name('faucet');
223
224 $app->post("/claim", $checkaddress($app, true), $checkclaim($app), function () use ($app) {
225     global $mysqli, $rewards, $recaptchaPrv, $referPercent;
226
227     $address = $app->view()->getData('address');
228     $resp = recaptcha_check_answer($recaptchaPrv, getIP(),
229         $app->request()->post('recaptcha_challenge_field'), $app->request()->post('recaptcha_response_field'));
230     if ($resp->is_valid) {
231         $canclaim = $app->view()->getData('canclaim');
232         if (!$canclaim) {
233             $app->redirect($app->urlFor('faucet'));
234         }
235         $referral = isset($_SESSION['referer']) ? $_SESSION['referer'] : 0;
236         $amount = $rewards[rand(0, count($rewards)-1)];
237         $sql = "INSERT INTO balances(balance, totalbalance, email, referredby) ";
238         $sql .= "VALUES($amount, $amount, '$address', $referral) ON DUPLICATE KEY ";
239         $sql .= "UPDATE balance = balance + $amount, totalbalance = totalbalance + $amount;";
240         sql_query($sql);
241         if ($mysqli->affected_rows == 2) {
242             // existing user, check referral
243             $referral_query = sql_query("SELECT referredby FROM balances WHERE email='$address'");
244             $referral = fetch_one($referral_query);
245         }
246
247         $ua = $mysqli->real_escape_string($_SERVER['HTTP_USER_AGENT']);
248         $ip = getIP();
249         $date = date("Y-m-d H:i:s");
250         $sql = "INSERT INTO dispenses(amount, dispensed, email, ip, useragent) ";
251         $sql .= "VALUES('$amount', '$date', '$address', '$ip', '$ua')";
252         sql_query($sql);
253
254         if ($referral != 0) {
255             $referredamount = $amount * ($referPercent / 100);
256             $sql = "UPDATE balances SET balance = balance + $referredamount, totalbalance = totalbalance + $referredamount ";
257             $sql .= "WHERE id='$referral'";
258             sql_query($sql);
259         }
260
261         $app->view()->setData('canClaim', true);
262         $app->view()->setData('nextClaim', relative_time(time()+1));
263         $app->flash('amount', $amount);
264     } else {
265         $app->flash('error', "CAPTCHA incorrect. Please try again.");
266     }
267     $app->redirect($app->urlFor('faucet'));
268 })->name('claim');
269
270 $app->post("/cashout", $checkaddress($app, true), function () use ($app) {
271     global $cashout;
272
273     $address = $app->view()->getData('address');
274     $balance_query = sql_query("SELECT balance FROM balances WHERE email='$address'");
275     if ($balance_query->num_rows) {
276         $balance = fetch_one($balance_query);
277         if ($balance >= $cashout) {
278             sql_query("UPDATE balances SET balance = balance - $balance WHERE email='$address'");
279             // race attacks check
280             $balance_query = sql_query("SELECT balance FROM balances WHERE email='$address'");
281             $balancecheck = fetch_one($balance_query);
282             if ($balancecheck >= 0) {
283                 try {
284                     sendMoney($address, $balance);
285                     $app->flash('sentamount', true);
286                 } catch (NoCashException $e) {
287                     $app->flash('error', "The site does not have enough coins to pay out! No balance deducted.");
288                     sql_query("UPDATE balances SET balance = balance + $balance WHERE email='$address'");
289                 } catch (Exception $e) {
290                     $response = $e->getMessage();
291                     $app->flash('error', "An error has occured - $response");
292                     sql_query("UPDATE balances SET balance = balance + $balance WHERE email='$address'");
293                 }
294             }
295         } else {
296             $app->flash('error', "Amount is too small");
297         }
298     } else {
299         $app->flash('error', "You don't have enough coins to cash out");
300     }
301     $app->redirect($app->urlFor('faucet'));
302 })->name('cashout');
303
304 $app->post("/faucet", function () use ($app) {
305     global $mysqli, $allowEmail, $allowCoin;
306     $address = $app->request()->post('address');
307
308     if (!checkaddress($address)) {
309         $err = array();
310         if ($allowCoin) {
311             $err[] = COIN_NAME;
312         }
313         if ($allowEmail) {
314             $err[] = "email";
315         }
316         $app->flash('error', "Not a valid ".implode("/", $err)." address!");
317         $app->redirect($app->urlFor('root'));
318     }
319
320     $_SESSION['address'] = $mysqli->real_escape_string($address);
321     $app->redirect($app->urlFor('faucet'));
322 })->name("post_faucet");
323
324 $app->get('/(:segments+)', function ($segments) use ($app) {
325     $app->redirect($app->urlFor('root'));
326 })->name('catchall');
327
328 $app->run();