· 10 years ago · Jan 12, 2016, 08:33 PM
1<?php
2
3$version = '62';
4
5
6if (get_magic_quotes_gpc()) {
7 $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
8 while (list($key, $val) = each($process)) {
9 foreach ($val as $k => $v) {
10 unset($process[$key][$k]);
11 if (is_array($v)) {
12 $process[$key][stripslashes($k)] = $v;
13 $process[] = &$process[$key][stripslashes($k)];
14 } else {
15 $process[$key][stripslashes($k)] = stripslashes($v);
16 }
17 }
18 }
19 unset($process);
20}
21
22if(stripos($_SERVER['REQUEST_URI'], '@') !== FALSE ||
23 stripos(urldecode($_SERVER['REQUEST_URI']), '@') !== FALSE) {
24 header("Location: ."); die('Please wait...');
25}
26
27session_start();
28header('Content-Type: text/html; charset=utf-8');
29ini_set('display_errors', false);
30
31$missing_configs = array();
32
33$session_prefix = crc32(__FILE__);
34
35$disable_curl = false;
36$verify_peer = true;
37$local_cafile = false;
38require_once("config.php");
39if(!isset($disable_admin_panel)) {
40 $disable_admin_panel = false;
41 $missing_configs[] = array(
42 "name" => "disable_admin_panel",
43 "default" => "false",
44 "desc" => "Allows to disable Admin Panel for increased security"
45 );
46}
47
48if(!isset($connection_options)) {
49 $connection_options = array(
50 'disable_curl' => $disable_curl,
51 'local_cafile' => $local_cafile,
52 'verify_peer' => $verify_peer,
53 'force_ipv4' => false
54 );
55}
56if(!isset($connection_options['verify_peer'])) {
57 $connection_options['verify_peer'] = $verify_peer;
58}
59
60if (!isset($display_errors)) $display_errors = false;
61ini_set('display_errors', $display_errors);
62if($display_errors)
63 error_reporting(-1);
64
65
66if(array_key_exists('HTTP_REFERER', $_SERVER)) {
67 $referer = $_SERVER['HTTP_REFERER'];
68} else {
69 $referer = "";
70}
71
72$host = parse_url($referer, PHP_URL_HOST);
73if($_SERVER['HTTP_HOST'] != $host) {
74 if (
75 array_key_exists("address_input_name", $_SESSION) &&
76 array_key_exists($_SESSION["address_input_name"], $_POST)
77 ) {
78 $_POST[$_SESSION['address_input_name']] = "";
79 if ($display_errors) trigger_error("REFERER CHECK FAILED, ASSUMING CSRF!");
80 }
81}
82
83
84require_once('libs/faucetbox.php');
85
86try {
87 $sql = new PDO($dbdsn, $dbuser, $dbpass, array(PDO::ATTR_PERSISTENT => true,
88 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
89} catch(PDOException $e) {
90 die("Can't connect to database. Check your config.php.");
91}
92
93
94$template_updates = array(
95 array(
96 "test" => "/address_input_name/",
97 "message" => "Name of the address field has to be updated. Please follow <a href='https://bitcointalk.org/index.php?topic=1094930.msg12231246#msg12231246'>these instructions</a>"
98 ),
99 array(
100 "test" => "/libs\/mmc\.js/",
101 "message" => "Add <code>".htmlspecialchars('<script type="text/javascript" src="libs/mmc.js"></script>')."</code> after jQuery in <code><head></code> section."
102 ),
103 array(
104 "test" => "/honeypot/",
105 "message" => "Add <code><pre>".htmlspecialchars('<input type="text" name="address" class="form-control" style="position: absolute; position: fixed; left: -99999px; top: -99999px; opacity: 0; width: 1px; height: 1px">')."<br>".htmlspecialchars('<input type="checkbox" name="honeypot" style="position: absolute; position: fixed; left: -99999px; top: -99999px; opacity: 0; width: 1px; height: 1px">')."</pre></code> near the input with name <code>".htmlspecialchars('<?php echo $data["address_input_name"]; ?>')."</code>."
106 )
107);
108
109$db_updates = array(
110 15 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('version', '15');"),
111 17 => array("ALTER TABLE `Faucetinabox_Settings` CHANGE `value` `value` TEXT NOT NULL;", "INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('balance', 'N/A');"),
112 33 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('ayah_publisher_key', ''), ('ayah_scoring_key', '');"),
113 34 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('custom_admin_link_default', 'true')"),
114 38 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('reverse_proxy', 'none')", "INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('default_captcha', 'recaptcha')"),
115 41 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('captchme_public_key', ''), ('captchme_private_key', ''), ('captchme_authentication_key', ''), ('reklamper_enabled', '')"),
116 46 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('last_balance_check', '0')"),
117 54 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('funcaptcha_public_key', ''), ('funcaptcha_private_key', '')"),
118 55 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('block_adblock', ''), ('button_timer', '0')"),
119 56 => array("INSERT IGNORE INTO `Faucetinabox_Settings` (`name`, `value`) VALUES ('ip_check_server', ''),('ip_ban_list', ''),('hostname_ban_list', ''),('address_ban_list', '')"),
120 58 => ["DELETE FROM `Faucetinabox_Settings` WHERE `name` IN ('captchme_public_key', 'captchme_private_key', 'captchme_authentication_key', 'reklamper_enabled')"],
121);
122
123$default_data_query = <<<QUERY
124create table if not exists Faucetinabox_Settings (
125 `name` varchar(64) not null,
126 `value` text not null,
127 primary key(`name`)
128);
129create table if not exists Faucetinabox_IPs (
130 `ip` varchar(20) not null,
131 `last_used` timestamp not null,
132 primary key(`ip`)
133);
134create table if not exists Faucetinabox_Addresses (
135 `address` varchar(60) not null,
136 `ref_id` int null,
137 `last_used` timestamp not null,
138 primary key(`address`)
139);
140create table if not exists Faucetinabox_Refs (
141 `id` int auto_increment not null,
142 `address` varchar(60) not null unique,
143 `balance` bigint unsigned default 0,
144 primary key(`id`)
145);
146create table if not exists Faucetinabox_Pages (
147 `id` int auto_increment not null,
148 `url_name` varchar(50) not null unique,
149 `name` varchar(255) not null,
150 `html` text not null,
151 primary key(`id`)
152);
153
154INSERT IGNORE INTO Faucetinabox_Settings (name, value) VALUES
155('apikey', ''),
156('timer', '180'),
157('rewards', '90*100, 10*500'),
158('referral', '15'),
159('solvemedia_challenge_key', ''),
160('solvemedia_verification_key', ''),
161('solvemedia_auth_key', ''),
162('recaptcha_private_key', ''),
163('recaptcha_public_key', ''),
164('ayah_publisher_key', ''),
165('ayah_scoring_key', ''),
166('funcaptcha_private_key', ''),
167('funcaptcha_public_key', ''),
168('name', 'Faucet in a Box'),
169('short', 'Just another Faucet in a Box :)'),
170('template', 'default'),
171('custom_body_cl_default', ''),
172('custom_box_bottom_cl_default', ''),
173('custom_box_bottom_default', ''),
174('custom_box_top_cl_default', ''),
175('custom_box_top_default', ''),
176('custom_box_left_cl_default', ''),
177('custom_box_left_default', ''),
178('custom_box_right_cl_default', ''),
179('custom_box_right_default', ''),
180('custom_css_default', '/* custom_css */\\n/* center everything! */\\n.row {\\n text-align: center;\\n}\\n#recaptcha_widget_div, #recaptcha_area {\\n margin: 0 auto;\\n}\\n/* do not center lists */\\nul, ol {\\n text-align: left;\\n}'),
181('custom_footer_cl_default', ''),
182('custom_footer_default', ''),
183('custom_main_box_cl_default', ''),
184('custom_palette_default', ''),
185('custom_admin_link_default', 'true'),
186('version', '$version'),
187('currency', 'BTC'),
188('balance', 'N/A'),
189('reverse_proxy', 'none'),
190('last_balance_check', '0'),
191('default_captcha', 'recaptcha'),
192('ip_check_server', ''),
193('ip_ban_list', ''),
194('hostname_ban_list', ''),
195('address_ban_list', ''),
196('block_adblock', ''),
197('button_timer', '0')
198;
199QUERY;
200
201// ****************** START ADMIN TEMPLATES
202$master_template = <<<TEMPLATE
203<!DOCTYPE html>
204<html>
205 <head>
206 <title>Faucet in a Box</title>
207 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/css/bootstrap.min.css">
208 <link rel="stylesheet" id="palette-css" href="data:text/css;base64,IA==">
209 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.2/css/bootstrap-select.min.css">
210 <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
211 <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/js/bootstrap.min.js"></script>
212 <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.2/js/bootstrap-select.min.js"></script>
213 <style type="text/css">
214 a, .btn, tr, td, .glyphicon{
215 transition: all 0.2s ease-in;
216 -o-transition: all 0.2s ease-in;
217 -webkit-transition: all 0.2s ease-in;
218 -moz-transition: all 0.2s ease-in;
219 }
220 .form-group {
221 margin: 15px !important;
222 }
223 textarea.form-control {
224 min-height: 120px;
225 }
226 .tab-content > .active {
227 border-radius: 0px 0px 4px 6px;
228 margin-top: -1px;
229 }
230 .prev-box {
231 border-radius: 4px;
232 }
233 .prev-box > .btn {
234 min-width: 45px;
235 height: 33px;
236 font-weight: bold;
237 }
238 .prev-box > .text-white {
239 text-shadow: 0 0 2px black;
240 }
241 .prev-box > .active {
242 margin-top: -2px;
243 height: 36px;
244 font-weight: bold;
245 font-size: 130%;
246 border-radius: 3px !important;
247 box-shadow: 0px 1px 2px #333;
248 }
249 .prev-box > .transparent {
250 border: 1px dotted #FF0000;
251 box-shadow: inset 0px 0px 5px #FFF;
252 }
253 .prev-box > .transparent.active {
254 box-shadow: 0px 1px 2px #333, inset 0px 0px 5px #FFF;
255 }
256 .picker-label {
257 padding-top: 11px;
258 }
259 .bg-black{
260 background: #000;
261 }
262 .bg-white{
263 background: #fff;
264 }
265 .text-black{
266 color: #000;
267 }
268 .text-white{
269 color: #fff;
270 }
271 </style>
272 </head>
273 <body>
274 <div class="container">
275 <h1>Welcome to your Faucet in a Box Admin Page!</h1><hr>
276 <:: content ::>
277 </div>
278 </body>
279</html>
280TEMPLATE;
281
282$admin_template = <<<TEMPLATE
283<noscript>
284 <div class="alert alert-danger text-center" role="alert">
285 <p class="lead">
286 You have disabled Javascript. Javascript is required for the admin panel to work!
287 </p>
288 </div>
289 <style>
290 #admin-content{ display: none !important; }
291 </style>
292</noscript>
293
294<:: oneclick_update_alert ::>
295<:: version_check ::>
296<:: changes_saved ::>
297<:: new_files ::>
298<:: connection_error ::>
299<:: curl_warning ::>
300<:: send_coins_message ::>
301<:: missing_configs ::>
302<:: template_updates ::>
303<:: nastyhosts_not_allowed ::>
304
305<form method="POST" id="admin-form" class="form-horizontal" role="form">
306
307 <div id="admin-content" role="tabpanel">
308
309 <!-- Nav tabs -->
310 <ul class="nav nav-tabs" role="tablist">
311 <li role="presentation" class="active"><a href="#basic" aria-controls="basic" role="tab" data-toggle="tab">Basic</a></li>
312 <li role="presentation"><a href="#captcha" aria-controls="captcha" role="tab" data-toggle="tab">Captcha</a></li>
313 <li role="presentation"><a href="#templates" aria-controls="templates" role="tab" data-toggle="tab">Templates</a></li>
314 <li role="presentation"><a href="#pages" aria-controls="pages" role="tab" data-toggle="tab">Pages</a></li>
315 <li role="presentation"><a href="#security" aria-controls="security" role="tab" data-toggle="tab">Security</a></li>
316 <li role="presentation"><a href="#advanced" aria-controls="advanced" role="tab" data-toggle="tab">Advanced</a></li>
317 <li role="presentation"><a href="#referrals" aria-controls="referrals" role="tab" data-toggle="tab">Referrals</a></li>
318 <li role="presentation"><a href="#send-coins" aria-controls="send-coins" role="tab" data-toggle="tab">Manually send coins</a></li>
319 <li role="presentation"><a href="#reset" aria-controls="reset" role="tab" data-toggle="tab">Factory reset</a></li>
320 </ul>
321
322 <div class="tab-content">
323 <div role="tabpanel" class="tab-pane active" id="basic">
324 <h2>Basic</h2>
325 <h3>Faucet Info</h3>
326 <div class="form-group">
327 <label for="name" class="control-label">Faucet name</label>
328 <input type="text" class="form-control" name="name" value="<:: name ::>">
329 </div>
330 <div class="form-group">
331 <label for="short" class="control-label">Short description</label>
332 <input type="text" class="form-control" name="short" value="<:: short ::>">
333 </div>
334
335 <h3>Access</h3>
336 <div class="row">
337 <div class="col-md-6">
338 <div class="form-group">
339 <:: invalid_key ::>
340 <label for="apikey" class="control-label">FaucetBOX.com API key</label>
341 <p>You can get it from <a href="https://faucetbox.com/">FaucetBOX.com dashboard</a> (you have to register and log in)</p>
342 <input type="text" class="form-control" name="apikey" value="<:: apikey ::>">
343 </div>
344 </div>
345 <div class="col-md-6">
346 <div class="form-group">
347 <label for="currency" class="control-label">Currency</label>
348 <p>Select currency you want to use.</p>
349 <select id="currency" class="form-control selectpicker" name="currency" id="currency">
350 <:: currencies ::>
351 </select>
352 </div>
353 </div>
354 </div>
355 <div class="row">
356 <div class="col-md-6">
357 <div class="form-group">
358 <label for="timer" class="control-label">Timer (in minutes)</label>
359 <p>How often users can get coins from you?</p>
360 <input type="text" class="form-control" name="timer" value="<:: timer ::>">
361 </div>
362 </div>
363 <div class="col-md-6">
364 <div class="form-group">
365 <label for="referral" class="control-label">Referral earnings:</label>
366 <p>in percents (0 to disable)</p>
367 <input type="text" class="form-control" name="referral" value="<:: referral ::>">
368 </div>
369 </div>
370 </div>
371 <div class="row">
372 <div class="col-md-6">
373 <div class="form-group">
374 <label for="button-timer" class="control-label">Enable <i>Get reward</i> button after some time</label>
375 <p>Enter number of seconds for which the <i>Get reward</i> button should be disabled</p>
376 <input type="text" class="form-control" name="button_timer" value="<:: button_timer ::>">
377 </div>
378 </div>
379 <div class="col-md-6">
380 <div class="form-group">
381 <label for="block-adblock" class="control-label"><input type="checkbox" name="block_adblock" <:: block_adblock ::> > Detect and block users with ad blocking software</label>
382 <p><i>Get reward</i> button will be disabled if AdBlock, uBlock or something similar is detected</p>
383 </div>
384 </div>
385 </div>
386 <h3>Rewards</h3>
387 <div class="form-group">
388 <p id="rewards-desc-nojs">How much users can get from you? You can set multiple rewards (separate them with a comma) and set weights for them, to define how plausible each reward will be. <br>Examples: <code>100</code>, <code>50, 150, 300</code>, <code>10*50, 2*100</code>. The last example means 50 satoshi or DOGE 10 out of 12 times, 100 satoshi or DOGE 2 out of 12 times.</p>
389 <p class="hidden" id="rewards-desc-js">
390 How much coins users can get from you? You can set multiple rewards using "Add reward" button. Amount can be either a number (ex. <code>100</code>) or a range (ex. <code>100-500</code>). Chance must be in percentage between 1 and 100. Sum of all chances must be equal 100%.
391 </p>
392 <p>Enter values in satoshi (1 satoshi of xCOIN = 0.00000001 xCOIN) for everything except DOGE. For DOGE it's in whole coins.</p>
393 <input id="rewards-raw" type="text" class="form-control" name="rewards" value="<:: rewards ::>">
394 <div id="rewards-box" class="hidden">
395 <div class="alert alert-info">
396 <b>PREVIEW:</b> Possible rewards: <span id="rewards-preview">loading...</span>
397 </div>
398 <table class="table">
399 <thead>
400 <tr>
401 <th>Amount</th>
402 <th>Chance (in %)</th>
403 <th class="text-center">Options</th>
404 </tr>
405 </thead>
406 <tbody>
407 </tbody>
408 </table>
409 <div class="alert alert-warning hidden rewards-warning">
410 Some incorrect fields were discarded. Amount can be either a number (eg. "100") or a range (eg. "100-200"). If amount is a range, the second number must be greater than the first one (eg. "200-100" is incorrect). Chance must be greater than 0 and lower than 100.
411 </div>
412 <div class="alert alert-danger hidden rewards-alert">
413 Sum of rewards' chances is not equal to 100 (%).
414 (<i class="math"></i>)
415 <a href="#" id="rewards-auto-fix" class="pull-right">Auto fix (this will remove all invalid rows)</a>
416 </div>
417 <button id="add-reward" class="btn btn-primary">Add reward</button>
418 </div>
419 </div>
420 </div>
421 <div role="tabpanel" class="tab-pane" id="captcha">
422 <h2>Captcha</h2>
423 <div class="row">
424 <div class="form-group">
425 <p class="alert alert-info">Some captcha systems may be unsafe and fail to stop bots. FunCaptcha is considered the safest, but you should always read opinions about your chosen Captcha system first.</p>
426 <label for="default_captcha" class="control-label">Default captcha:</label>
427 <select class="form-control selectpicker" name="default_captcha" id="default_captcha">
428 <option value="SolveMedia">SolveMedia</option>
429 <option value="reCaptcha">reCaptcha</option>
430 <option value="AreYouAHuman">Are You A Human</option>
431 <option value="FunCaptcha">FunCaptcha</option>
432 </select>
433 </div>
434 </div>
435 <div class="row">
436 <div class="col-lg-6 col-md-6">
437 <div class="well">
438 <h4>reCaptcha</h4>
439 <div class="form-group" id="recaptcha">
440 <p>Get your keys <a href="https://www.google.com/recaptcha/admin#list">here</a>.</p>
441 <label for="recaptcha_public_key" class="control-label">reCaptcha public key:</label>
442 <input type="text" class="form-control" name="recaptcha_public_key" value="<:: recaptcha_public_key ::>">
443 <label for="recaptcha_private_key" class="control-label">reCaptcha private key:</label>
444 <input type="text" class="form-control" name="recaptcha_private_key" value="<:: recaptcha_private_key ::>">
445 <label><input type="checkbox" class="captcha-disable-checkbox"> Turn on this captcha system</label>
446 </div>
447 </div>
448 </div>
449 <div class="col-lg-6 col-md-6">
450 <div class="well">
451 <h4>Are You A Human</h4>
452 <div class="form-group" id="ayah">
453 <p>Get your keys <a href="https://portal.areyouahuman.com/dashboard">here</a>.</p>
454 <label for="ayah_publisher_key" class="control-label">Are You A Human publisher key:</label>
455 <input type="text" class="form-control" name="ayah_publisher_key" value="<:: ayah_publisher_key ::>">
456 <label for="ayah_scoring_key" class="control-label">Are You A Human scoring key:</label>
457 <input type="text" class="form-control" name="ayah_scoring_key" value="<:: ayah_scoring_key ::>">
458 <label><input type="checkbox" class="captcha-disable-checkbox"> Turn on this captcha system</label>
459 </div>
460 </div>
461 </div>
462 </div>
463 <div class="row">
464 <div class="col-lg-6 col-md-6">
465 <div class="well">
466 <h4>SolveMedia</h4>
467 <div class="form-group" id="solvemedia">
468 <p>Get your keys <a href="https://portal.solvemedia.com/portal/">here</a> (select <em>Sites</em> from the menu after logging in).</p>
469 <label for="solvemedia_challenge_key" class="control-label">SolveMedia challenge key:</label>
470 <input type="text" class="form-control" name="solvemedia_challenge_key" value="<:: solvemedia_challenge_key ::>">
471 <label for="solvemedia_verification_key" class="control-label">SolveMedia verification key:</label>
472 <input type="text" class="form-control" name="solvemedia_verification_key" value="<:: solvemedia_verification_key ::>">
473 <label for="solvemedia_auth_key" class="control-label">SolveMedia authentication key:</label>
474 <input type="text" class="form-control" name="solvemedia_auth_key" value="<:: solvemedia_auth_key ::>">
475 <label><input type="checkbox" class="captcha-disable-checkbox"> Turn on this captcha system</label>
476 </div>
477 </div>
478 </div>
479 <div class="col-lg-6 col-md-6">
480 <div class="well">
481 <h4>FunCaptcha</h4>
482 <div class="form-group" id="funcaptcha">
483 <p>Get your keys <a href="https://www.funcaptcha.com/domain-settings">here</a>.</p>
484 <label for="funcaptcha_public_key" class="control-label">FunCaptcha public key:</label>
485 <input type="text" class="form-control" name="funcaptcha_public_key" value="<:: funcaptcha_public_key ::>">
486 <label for="funcaptcha_private_key" class="control-label">FunCaptcha private key:</label>
487 <input type="text" class="form-control" name="funcaptcha_private_key" value="<:: funcaptcha_private_key ::>">
488 <label><input type="checkbox" class="captcha-disable-checkbox"> Turn on this captcha system</label>
489 </div>
490 </div>
491 </div>
492 </div>
493 </div>
494 <div role="tabpanel" class="tab-pane" id="templates">
495 <h2>Template options</h2>
496 <div class="form-group">
497 <div class="col-xs-12 col-sm-2 col-lg-1">
498 <label for="template" class="control-label">Template:</label>
499 </div>
500 <div class="col-xs-3">
501 <select id="template-select" name="template" class="selectpicker"><:: templates ::></select>
502 </div>
503 </div>
504 <div id="template-options">
505 <:: template_options ::>
506 </div>
507 </div>
508 <div role="tabpanel" class="tab-pane" id="pages">
509 <h2>Pages</h2>
510 <p>Here you can create, delete and edit custom static pages.</p>
511 <ul class="nav nav-tabs pages-nav" role="tablist">
512 <li class="pull-right"><button type="button" id="pageAddButton" class="btn btn-info"><span class="glyphicon">+</span> Add new page</button></li>
513 <:: pages_nav ::>
514 </ul>
515 <div id="pages-inner" class="tab-content">
516 <:: pages ::>
517 </div>
518 </div>
519 <div role="tabpanel" class="tab-pane" id="security">
520 <h2>Security</h2>
521 <h3>Bot protection</h3>
522 <div class="form-group">
523 <label for="ip_check_server" class="control-label">Use external IP address check service (it'll also report suspicious addresses to this service):</label>
524 <select id="ip_check_server" name="ip_check_server" class="form-control selectpicker">
525 <option value="http://v1.nastyhosts.com/">NastyHosts.com</option>
526 <option value="">Disabled</option>
527 </select>
528 </div>
529 <div class="form-group">
530 <label for="ip_ban_list" class="control-label">List of IP addresses or IP networks in CIDR notation to ban (one value per line)</label>
531 <textarea class="form-control" name="ip_ban_list" id="ip_ban_list" placeholder="Example value:
532127.0.0.0/8
533172.16.0.1
534192.168.0.0/24"><:: ip_ban_list ::></textarea>
535 </div>
536 <div class="form-group">
537 <label for="hostname_ban_list" class="control-label">List of hostnames to ban. Partial match is enough. Requires external IP address check service enabled. (one value per line)</label>
538 <textarea class="form-control" name="hostname_ban_list" id="hostname_ban_list" placeholder="Example value:
539proxy
540compute.amazonaws.com"><:: hostname_ban_list ::></textarea>
541 </div>
542 <div class="form-group">
543 <label for="address_ban_list" class="control-label">List of cryptocurrency addresses to ban (one address per line)</label>
544 <textarea class="form-control" name="address_ban_list" id="address_ban_list" placeholder="Example value:
5451HmUrGAf4Bz9KMX6Pg67RA2VZgWVPnpyvS
54613q29zfcesTiZoed1BNFr3VYr4zBGfuwW4"><:: address_ban_list ::></textarea>
547 </div>
548 </div>
549 <div role="tabpanel" class="tab-pane" id="advanced">
550 <h2>Advanced</h2>
551 <h3>Reverse Proxy</h3>
552 <div class="form-group">
553 <p class="alert alert-danger"><b>Be careful! This is an advanced feature. Don't use it unless you know what you're doing. If you set it wrong or you don't properly configure your proxy AND your server YOU MAY LOSE YOUR COINS!</b></p>
554 <p class="alert alert-info">This feature is experimental! It may not work properly and may lead you to losing coins. You have been warned.</p>
555 <p>This setting allows you to change the method of identifying users. By default Faucet in a Box will use the connecting IP address. Hovewer if you're using a reverse proxy, like CloudFlare or Incapsula, the connecting IP address will always be the address of the proxy. That results in all faucet users sharing the same timer. If you set this option to a correct proxy, then Faucet in a Box will use a corresponding HTTP Header instead of IP address.</p>
556 <p>However you MUST prevent anyone from bypassing the proxy. HTTP Headers can be spoofed, so if someone can access your page directly, then he can send his own headers, effectively ignoring the timer you've set and stealing all your coins!</p>
557 <p>Faucet in a Box has a security feature that will disable Reverse Proxy support if it detects any connection that has bypassed the proxy. Hovewer the detection is not perfect, so you shouldn't rely on it. Instead make proper precautions, for example by configuring your firewall to only allow connections from your proxy IP addresses.</p>
558 <p>If you're using a Reverse Proxy (CloudFlare or Incapsula) choose it from the list below. If your provider is not listed below contact us at support@faucetbox.com</p>
559 <p><em>None</em> is always a safe setting, but - as explained above - the timer may be shared between all your users if you're using a proxy.</p>
560 <:: reverse_proxy_changed_alert ::>
561 <label for="reverse_proxy" class="control-label">Reverse Proxy provider:</label>
562 <select id="reverse_proxy" name="reverse_proxy" class="form-control selectpicker">
563 <option value="cloudflare">CloudFlare (CF-Connecting-IP)</option>
564 <option value="incapsula">Incapsula (Incap-Client-IP)</option>
565 <option value="none">None (Connecting IP address)</option>
566 </select>
567 </div>
568 </div>
569 <div role="tabpanel" class="tab-pane" id="referrals">
570 <h2>Referrals</h2>
571 <div class="alert alert-info">
572 On this tab you can check all addresses which have referral.
573 </div>
574 <div class="row" style="padding: 15px 0 30px;">
575 <div class="col-md-10">
576 <input type="text" class="form-control" id="referral_address" value="" placeholder="Referral address">
577 </div>
578 <div class="col-md-2">
579 <button class="btn btn-primary" id="check_referral" style="width: 100%;">Check</button>
580 </div>
581 </div>
582 <div class="alert alert-danger hidden" id="referral-ajax-error">
583 An error occurred while receiving addresses with this referral. Please try again later or contact <a href="http://faucetbox.com/support" target="_blank">support team</a>.
584 </div>
585 <table class="table hidden" id="referral_list">
586 <thead>
587 <tr>
588 <th>#</th>
589 <th>Address</th>
590 <th>Referral</th>
591 </tr>
592 </thead>
593 <tbody>
594
595 </tbody>
596 </table>
597
598 <div style="height: 30px;"></div>
599
600 </div>
601 <div role="tabpanel" class="tab-pane" id="send-coins">
602 <h2>Manually send coins</h2>
603 <div class="form-group">
604 <p class="alert alert-info">You can use the form below to send coins to given address manaully</p>
605 <label for="" class="control-label">Amount in satoshi:</label>
606 <input type="text" class="form-control" name="send_coins_amount" value="1" id="input_send_coins_amount">
607 <label for="" class="control-label">Currency:</label>
608 <input type="text" class="form-control" name="send_coins_currency" value="<:: currency ::>" disabled>
609 <label for="" class="control-label">Receiver address:</label>
610 <input type="text" class="form-control" name="send_coins_address" value=""id="input_send_coins_address">
611 </div>
612 <div class="form-group">
613 <div class="alert alert-info">
614 Are you sure you would like to send <span id="send_coins_satoshi">0</span> satoshi (<span id="send_coins_bitcoins">0.00000000</span> <:: currency ::>) to <span id="send_coins_address">address</span>?
615 <input class="btn btn-primary pull-right" style="margin-top: -7px;" type="submit" name="send_coins" value="Yes, send coins">
616 </div>
617 </div>
618 </div>
619 <div role="tabpanel" class="tab-pane" id="reset">
620 <h2>Factory reset</h2>
621 <div class="alert alert-danger">
622 This will reset all settings except: API key, captcha keys, admin password and pages. Deleted data can't be recovered!<br>
623 Please select the checkbox to confirm and click button below.
624 </div>
625 <div class="text-center">
626 <label>
627 <input type="checkbox" name="factory_reset_confirm">
628 Yes, I want to reset back to factory settings
629 </label>
630 </div>
631 <div class="text-center">
632 <input type="submit" name="reset" class="btn btn-warning btn-lg" style="" value="Reset settings to defaults">
633 </div>
634 </div>
635 </div>
636
637 </div>
638
639 <hr>
640
641 <div class="form-group">
642 <button type="submit" name="save_settings" class="btn btn-success btn-lg">
643 <span class="glyphicon glyphicon-ok"></span>
644 Save changes
645 </button>
646 <a href="?p=logout" class="btn btn-default btn-lg pull-right">
647 <span class="glyphicon glyphicon-log-out"></span>
648 Logout
649 </a>
650 </div>
651 <script type="text/javascript">
652
653 if (typeof btoa == "undefined") {
654 // discuss at: http://phpjs.org/functions/base64_encode/
655 // original by: Tyler Akins (http://rumkin.com)
656 // improved by: Bayron Guevara
657 // improved by: Thunder.m
658 // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
659 // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
660 // improved by: Rafał Kukawski (http://kukawski.pl)
661 // bugfixed by: Pellentesque Malesuada
662 function btoa(e){var t,r,c,a,n,h,o,A,i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",d=0,l=0,u="",C=[];if(!e)return e;e=unescape(encodeURIComponent(e));do t=e.charCodeAt(d++),r=e.charCodeAt(d++),c=e.charCodeAt(d++),A=t<<16|r<<8|c,a=A>>18&63,n=A>>12&63,h=A>>6&63,o=63&A,C[l++]=i.charAt(a)+i.charAt(n)+i.charAt(h)+i.charAt(o);while(d<e.length);u=C.join("");var s=e.length%3;return(s?u.slice(0,s-3):u)+"===".slice(s||3)}
663 }
664
665
666 function renumberPages(){
667 $(".pages-nav > li").each(function(index){
668 if(index != 0){
669 $(this).children().first().attr("href", "#page-wrap-" + index);
670 $(this).children().first().text("Page " + index);
671 }
672 });
673 $("#pages-inner > div.tab-pane").each(function(index){
674 var i = index+1;
675 $(this).attr("id", "page-wrap-" + i);
676 $(this).children().each(function(i2){
677 var ending = "html";
678 var item = "textarea";
679 if(i2 == 0){
680 ending = "name";
681 item = "input";
682 }
683
684 $(this).children('label').attr("for", "pages." + i + "." + ending);
685 $(this).children(item).attr("id", "pages." + i + "." + ending).attr("name", "pages[" + i + "][" + ending + "]");
686 });
687 });
688 }
689
690 function deletePage(btn) {
691 $(btn).parent().remove();
692 $(".pages-nav > .active").remove();
693 $(".pages-nav > li:nth-child(2) > a").tab('show');
694 renumberPages();
695 }
696
697 function reloadSendCoinsConfirmation() {
698
699 var satoshi = $("#input_send_coins_amount").val();
700 var bitcoin = satoshi / 100000000;
701 var address = $("#input_send_coins_address").val();
702
703 $("#send_coins_satoshi").text(satoshi);
704 $("#send_coins_bitcoins").text(bitcoin.toFixed(8));
705 $("#send_coins_address").text(address);
706
707 }
708
709 var tmp = [];
710
711 $(function() {
712
713 $("#check_referral").click(function (e) {
714
715 $(this).attr("disabled", true).text("Checking...");
716
717 $.ajax(document.location.href, {method: "POST", data: {action: "check_referrals", referral: $("#referral_address").val()}})
718 .done(function (data) {
719
720 $("#check_referral").attr("disabled", false).text("Check");
721
722 if (data.status == 200) {
723
724 $("#referral-ajax-error").addClass("hidden");
725
726 $("#referral_list").removeClass("hidden").find("tbody").html("");
727
728 for (i in data.addresses) {
729 var el = data.addresses[i];
730
731 $("#referral_list tbody").append(
732 $("<tr>").append(
733 $("<td>").html( (i+1) + "." )
734 ).append(
735 $("<td>").text(el.address).append(
736 $("<span>").addClass("glyphicon glyphicon-chevron-right pull-right")
737 )
738 ).append(
739 $("<td>").text(el.referral)
740 )
741 );
742
743 }
744
745 if (data.addresses.length == 0) {
746 $("#referral_list tbody").append(
747 $("<tr>").append(
748 $("<td>").attr("colspan", 5).append(
749 $("<p>").addClass("lead text-center text-muted").text("No addresses found")
750 )
751 )
752 );
753 }
754
755 } else {
756 $("#referral-ajax-error").removeClass("hidden");
757 $("#referral_list").addClass("hidden");
758 }
759
760 }).fail(function () {
761 $("#referral-ajax-error").removeClass("hidden");
762 $("#referral_list").addClass("hidden");
763 });
764
765 });
766
767 $("#admin-form").submit(function (e) {
768 e.preventDefault();
769 });
770
771 $("#admin-form input[type=submit], #admin-form button[type=submit]").click(function (e) {
772 e.preventDefault();
773 var data = btoa($("#admin-form").serialize());
774 $("<form>").attr("method", "POST").append(
775 $("<input>")
776 .attr("type", "hidden")
777 .attr("name", "encoded_data")
778 .val(data)
779 ).append(
780 $("<input>")
781 .attr("type", "hidden")
782 .attr("name", $(this).attr("name"))
783 .val( $(this).val().length > 0 ? $(this).val() : $(this).text() )
784 ).hide().appendTo('body').submit();
785 });
786
787 $("#input_send_coins_amount, #input_send_coins_address").change(reloadSendCoinsConfirmation).keydown(reloadSendCoinsConfirmation).keyup(reloadSendCoinsConfirmation).keypress(reloadSendCoinsConfirmation);
788
789 $("#pageAddButton").click(function() {
790 var i = $("#pages-inner").children("div").length.toString();
791 var j = parseInt(i)+1;
792 var newpage = <:: page_form_template ::>
793 .replace(/<:: i ::>/g, i)
794 .replace("<:: html ::>", '')
795 .replace("<:: page_name ::>", '');
796 $("#pages-inner").append(newpage);
797 var newtab = <:: page_nav_template ::>
798 .replace(/<:: i ::>/g, i);
799 $('.pages-nav').append(newtab);
800 renumberPages();
801 $(".pages-nav > li").last().children().first().tab('show');
802 });
803 $(".pages-nav > li:nth-child(2)").addClass('active');
804 $('#pages-inner').children().first().addClass('active');
805
806 $('.pages-nav a').click(function (e) {
807 e.preventDefault();
808 $(this).tab('show');
809 });
810 $("#template-select").change(function() {
811 var t = $(this).val();
812 $.post("", { "get_options": t }, function(data) { $("#template-options").html(data); $('.selectpicker').selectpicker(); });
813 });
814 $("#reverse_proxy").val("<:: reverse_proxy ::>"); //must be before selectpicker render
815 $("#default_captcha").val("<:: default_captcha ::>"); //must be before selectpicker render
816 $("#ip_check_server").val("<:: ip_check_server ::>"); //must be before selectpicker render
817 $('.selectpicker').selectpicker(); //render selectpicker on page load
818
819 $('.nav-tabs a').click(function (e) {
820 e.preventDefault()
821 $(this).tab('show');
822 if (typeof localStorage !== "undefined") {
823 localStorage["current_tab"] = $(this).attr('href');
824 }
825 });
826
827 if (typeof localStorage !== "undefined" && typeof localStorage["current_tab"] !== "undefined") {
828 $('a[href=' + localStorage["current_tab"] + ']').tab('show');
829 }
830
831 $(".captcha-disable-checkbox").each(function(){
832 $(this).parent().parent().find("input[type=text]").each(function(){
833 if ($(this).val() == '') {
834 $(this).parent().find(".captcha-disable-checkbox").attr("checked", false);
835 $(this).parent().find("input[type=text]").attr("readonly", true);
836 } else {
837 $(this).parent().find(".captcha-disable-checkbox").attr("checked", true);
838 $(this).parent().find("input[type=text]").attr("readonly", false);
839 }
840 });
841 }).change(function(){
842 if ($(this).prop("checked")) {
843 $(this).parent().parent().find("input[type=text]").each(function(){
844 $(this).val(tmp[$(this).attr("name")]);
845 $(this).attr("readonly", false);
846 });
847 } else {
848 $(this).parent().parent().find("input[type=text]").each(function(){
849 tmp[$(this).attr("name")] = $(this).val();
850 $(this).val("");
851 $(this).attr("readonly", true);
852 });
853 }
854 });
855
856 RewardsSystem.init();
857 });
858
859
860
861var RewardsSystem = {
862
863 init: function() {
864
865 $('#rewards-raw').addClass('hidden');
866 $('#rewards-box').removeClass('hidden');
867
868 $('#rewards-desc-nojs').addClass('hidden');
869 $('#rewards-desc-js').removeClass('hidden');
870
871 $('#add-reward').click(function (e) {
872 e.preventDefault();
873 RewardsSystem.addRow();
874 });
875
876 $('#rewards-auto-fix').click(function (e) {
877 e.preventDefault();
878 RewardsSystem.autoFix();
879 RewardsSystem.autoFix();
880 });
881
882 $('#currency').change(RewardsSystem.rewardsUpdate);
883
884 RewardsSystem.fromRawData();
885
886 },
887
888 fromRawData: function() {
889 var rewards = [];
890
891 var raw = $('#rewards-raw').val().trim().split(' ');
892 for (i in raw) {
893 var reward = raw[i];
894 if (reward.trim() == '') continue;
895 reward = reward.split('*');
896 if (typeof reward[1] == 'undefined') {
897 rewards[rewards.length] = {
898 amount: RewardsSystem.parseAmount(reward[0]),
899 chance: 1
900 };
901 } else {
902 rewards[rewards.length] = {
903 amount: RewardsSystem.parseAmount(reward[1]),
904 chance: parseFloat(parseFloat(reward[0]).toFixed(2))
905 };
906 }
907 }
908
909 var chance_sum = 0;
910
911 for (i in rewards) {
912 chance_sum += rewards[i].chance;
913 }
914
915 rewards.sort(function (a,b) {
916 return b.chance - a.chance;
917 });
918
919 RewardsSystem.updateCurrentRewrads(rewards, chance_sum);
920 RewardsSystem.rewardsUpdate();
921 },
922
923 addRow: function () {
924 var tr = $('<tr>')
925 .append(
926 $('<td>').addClass('form-group').append(
927 $('<input>').addClass('form-control reward-amount').attr({
928 type: 'text'
929 })
930 )
931 )
932 .append(
933 $('<td>').addClass('form-group').append(
934 $('<input>').addClass('form-control reward-chance').attr({
935 type: 'number',
936 min: '1',
937 step: '0.01'
938 })
939 )
940 )
941 .append(
942 $('<td>').addClass('text-center').append(
943 $('<span>').addClass('btn btn-warning').text('Delete')
944 )
945 );
946 tr.find('span').click(RewardsSystem.delete);
947 tr.find('input').on('change click blur keypress keydown keyup', RewardsSystem.rewardsUpdate);
948
949 $('#rewards-box table tbody').append(tr);
950 },
951
952 getCurrentRewards: function () {
953 var rewards = [];
954 var sum_chance = 0;
955 $('#rewards-box table tbody tr').each(function (i, t) {
956 var amount = $(t).find('.reward-amount').val().trim();
957 var chance = parseFloat($(t).find('.reward-chance').val().trim());
958 if (isNaN(chance)) chance = 0;
959 if (RewardsSystem.validateAmount(amount) && !isNaN(chance) && chance > 0) {
960 chance = parseFloat(chance.toFixed(2));
961 sum_chance += chance;
962 rewards[rewards.length] = {
963 amount: amount,
964 chance: chance
965 };
966 }
967 });
968 return {
969 'rewards': rewards,
970 'sum': sum_chance
971 };
972 },
973
974 updateCurrentRewrads: function (rewards, sum) {
975 if (typeof sum == 'undefined') sum = 100;
976 $('#rewards-box table tbody').html('');
977 for (i in rewards) {
978 var reward = rewards[i];
979 RewardsSystem.addRow();
980 $('#rewards-box table tr').last().find('.reward-amount').val(reward.amount);
981 $('#rewards-box table tr').last().find('.reward-chance').val(parseFloat((reward.chance / sum * 100.0).toFixed(2)));
982 }
983 },
984
985 delete: function () {
986 $(this).parent().parent().remove();
987 RewardsSystem.rewardsUpdate();
988 },
989
990 autoFix: function() {
991 var rewards = RewardsSystem.getCurrentRewards();
992 var diff = rewards.sum / 100;
993
994 rewards.sum = 0;
995 rewards.count = 0;
996 rewards.omit = 0;
997 for (i in rewards.rewards) {
998 if (rewards.rewards[i].chance / diff >= 1) {
999 rewards.sum += rewards.rewards[i].chance;
1000 rewards.count++;
1001 } else {
1002 rewards.omit += rewards.rewards[i].chance;
1003 }
1004 }
1005
1006 var diff = rewards.sum / (100-rewards.omit);
1007
1008 for (i in rewards.rewards) {
1009 if (rewards.rewards[i].chance / diff >= 1) {
1010 rewards.rewards[i].chance = rewards.rewards[i].chance / diff;
1011 }
1012 }
1013
1014 RewardsSystem.updateCurrentRewrads(rewards.rewards);
1015 RewardsSystem.rewardsUpdate();
1016 },
1017
1018 parseAmount: function (amount) {
1019
1020 var new_amount = '';
1021
1022 for (i = 0; i < amount.length; i++) {
1023
1024 var char = amount[i];
1025
1026 if (char == ',') char = '.';
1027
1028 if (char == '.' && i == 0) {
1029 new_amount += '0.';
1030 } else if (!isNaN(parseInt(char)) || ((char == '-' || char == '.') && i > 0 && i < amount.length-1)) {
1031 new_amount += char;
1032 }
1033
1034 }
1035
1036 return new_amount;
1037
1038 },
1039
1040 validateAmount: function(amount) {
1041 if (amount.indexOf('-') != -1) {
1042 var from = parseFloat(amount.substring(0, amount.indexOf('-')));
1043 var to = parseFloat(amount.substring(amount.indexOf('-')+1));
1044 return (!isNaN(from) && !isNaN(to) && to > from && from > 0);
1045 } else {
1046 var num = parseFloat(amount);
1047 return (!isNaN(num) && num > 0);
1048 }
1049 },
1050
1051 rewardsUpdate: function (e) {
1052
1053 if (typeof e == 'undefined' || typeof e.type == 'undefined') {
1054 e = {
1055 type: ''
1056 };
1057 }
1058
1059 var raw = '';
1060 var preview = '';
1061
1062 var new_chance_sum = 0.0;
1063 var chance_math = '';
1064
1065
1066 $('.rewards-warning').addClass('hidden');
1067
1068 $('#rewards-box table tbody tr').each(function (i, t) {
1069
1070
1071 var amount = RewardsSystem.parseAmount($(t).find('.reward-amount').val().trim());
1072 var chance = parseFloat($(t).find('.reward-chance').val().trim());
1073
1074 if (isNaN(chance)) chance = 0;
1075
1076 $(t).find('.reward-amount').parent().removeClass('has-warning');
1077 $(t).find('.reward-chance').parent().removeClass('has-warning');
1078
1079 var validAmount = RewardsSystem.validateAmount(amount);
1080 var validChance = (!isNaN(chance) && chance > 0);
1081
1082 if (validAmount && validChance) {
1083
1084 chance = parseFloat(chance.toFixed(2));
1085
1086 if ($(t).find('.reward-amount').val() != amount && e.type == 'blur') {
1087 $(t).find('.reward-amount').val(amount);
1088 }
1089 if ($(t).find('.reward-chance').val() != chance) {
1090 $(t).find('.reward-chance').val(chance);
1091 }
1092
1093 new_chance_sum += chance;
1094 chance_math += (i > 0 ? ' + ' : '') + chance + '%';
1095
1096 raw += (i > 0 ? ', ' : '') + chance + '*' + amount;
1097 preview += (i > 0 ? ', ' : '') + amount + ' (' + chance + '%)';
1098
1099 } else if ((!validAmount && validChance) || (validAmount && !validChance)) {
1100 $('.rewards-warning').removeClass('hidden');
1101 if (!validAmount) {
1102 $(t).find('.reward-amount').parent().addClass('has-warning');
1103 }
1104 if (!validChance) {
1105 $(t).find('.reward-chance').parent().addClass('has-warning');
1106 }
1107 }
1108
1109 });
1110
1111 $('#rewards-raw').val(raw);
1112 $('#rewards-preview').text(preview + ' ' + ($('#currency').val() == 'DOGE' ? 'DOGE' : 'satoshi'));
1113
1114 if (parseFloat(new_chance_sum.toFixed(2)) != '100') {
1115 $('.rewards-alert').removeClass('hidden');
1116 $('.rewards-alert .math').text(chance_math + ' = ' + new_chance_sum.toFixed(2) + '%');
1117 } else {
1118 $('.rewards-alert').addClass('hidden');
1119 }
1120
1121 },
1122
1123};
1124
1125
1126 </script>
1127</form>
1128TEMPLATE;
1129
1130$admin_login_template = <<<TEMPLATE
1131<form method="POST" class="form-horizontal" role="form">
1132 <div class="form-group">
1133 <label for="password" class="control-label">Password:</label>
1134 <input type="password" class="form-control" name="password">
1135 </div>
1136 <div class="form-group">
1137 <input type="submit" class="btn btn-primary btn-lg" value="Login">
1138 </div>
1139</form>
1140<div class="alert alert-warning alert-dismissible" role="alert">
1141 <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
1142Don't remember? <a href="?p=password-reset">Reset your password</a>.
1143</div>
1144TEMPLATE;
1145
1146$session_error_template = <<<TEMPLATE
1147<div class="alert alert-danger" role="alert">
1148 There was a problem with accessing your session data on the server. Check your server logs and contact your hosting provider for further help.
1149</div>
1150TEMPLATE;
1151
1152$login_error_template = <<<TEMPLATE
1153<div class="alert alert-danger" role="alert">
1154 <span class="glyphicon glyphicon-remove"></span>
1155 Incorrect password.
1156</div>
1157TEMPLATE;
1158
1159$pass_template = <<<TEMPLATE
1160<div class="alert alert-info" role="alert">
1161 Your password: <:: password ::>. Make sure to save it. <a class="alert-link" href="?p=admin">Click here to continue</a>.
1162</div>
1163TEMPLATE;
1164
1165$pass_reset_template = <<<TEMPLATE
1166<form method="POST">
1167 <div class="form-group">
1168 <label for="dbpass" class="control-label">To reset your Admin Password, enter your database password here:</label>
1169 <input type="password" class="form-control" name="dbpass">
1170 </div>
1171 <p class="form-group alert alert-info" role="alert">
1172 You must enter the same password you've entered in your config.php file.
1173 </p>
1174 <input type="submit" class="form-group pull-right btn btn-warning" value="Reset password">
1175</form>
1176TEMPLATE;
1177
1178$invalid_key_error_template = <<<TEMPLATE
1179<div class="alert alert-danger" role="alert">
1180 You've entered an invalid API key!
1181</div>
1182TEMPLATE;
1183
1184$oneclick_update_button_template = <<<TEMPLATE
1185or
1186<input type="hidden" name="task" value="oneclick-update">
1187<input type="submit" class="btn btn-primary" value="Update automatically">
1188TEMPLATE;
1189
1190$new_version_template = <<<TEMPLATE
1191<form method="POST">
1192 <div class="alert alert-info alert-dismissible" role="alert">
1193 <button type="button" class="close" data-dismiss="alert">
1194 <span aria-hidden="true">×</span>
1195 <span class="sr-only">Close</span>
1196 </button>
1197 <span style="line-height: 34px">
1198 There's a new version of Faucet in a Box available!
1199 Your version: $version; new version: <b><:: version ::></b>
1200 </span>
1201 <span class="pull-right text-right">
1202 <a class="btn btn-primary" href="<:: url ::>" target="_blank">Download version <:: version ::></a>
1203 <:: oneclick_update_button ::>
1204 <br><br>
1205 <a href="https://faucetinabox.com/#update" target="_blank">
1206 Manual update instructions
1207 </a>
1208 </span>
1209 <:: changelog ::>
1210 </div>
1211</form>
1212TEMPLATE;
1213
1214$page_nav_template = <<<TEMPLATE
1215 <li><a href="#page-wrap-<:: i ::>" role="tab" data-toggle="tab">Page <:: i ::></a></li>
1216TEMPLATE;
1217
1218$page_form_template = <<<TEMPLATE
1219<div class="page-wrap panel panel-default tab-pane" id="page-wrap-<:: i ::>">
1220 <div class="form-group">
1221 <label class="control-label" for="pages.<:: i ::>.name">Page name:</label>
1222 <input class="form-control" type="text" id="pages.<:: i ::>.name" name="pages[<:: i ::>][name]" value="<:: page_name ::>">
1223 </div>
1224 <div class="form-group">
1225 <label class="control-label" for="pages.<:: i ::>.html">HTML content:</label>
1226 <textarea class="form-control" id="pages.<:: i ::>.html" name="pages[<:: i ::>][html]"><:: html ::></textarea>
1227 </div>
1228 <button type="button" class="btn btn-sm pageDeleteButton" onclick="deletePage(this);">Delete this page</button>
1229</div>
1230TEMPLATE;
1231
1232$changes_saved_template = <<<TEMPLATE
1233<p class="alert alert-success">
1234 <span class="glyphicon glyphicon-ok"></span>
1235 Changes successfully saved!
1236</p>
1237TEMPLATE;
1238
1239$oneclick_update_success_template = <<<TEMPLATE
1240<p class="alert alert-success">
1241 <span class="glyphicon glyphicon-ok"></span>
1242 Faucet in a BOX script was successfully updated to the newest version!
1243</p>
1244TEMPLATE;
1245
1246$nastyhosts_not_allowed_template = <<<TEMPLATE
1247<p class="alert alert-danger">
1248 <span class="glyphicon glyphicon-remove"></span>
1249 You can't enable NastyHosts.com, because your IP address is marked as suspicious and you won't be able to access Admin Panel.
1250</p>
1251TEMPLATE;
1252
1253$oneclick_update_fail_template = <<<TEMPLATE
1254<p class="alert alert-danger">
1255 <span class="glyphicon glyphicon-remove"></span>
1256 An error occurred while updating Faucet in a BOX script. Please install new version manually.
1257</p>
1258TEMPLATE;
1259
1260$new_files_template = <<<TEMPLATE
1261<div class="alert alert-danger">
1262 Some of your template files need to be updated manually. Please compare original and new files and merge the changes:
1263 <ul>
1264 <:: new_files ::>
1265 </ul>
1266 Remember to remove <code>.new</code> files when you're done.
1267</div>
1268TEMPLATE;
1269
1270$connection_error_template = <<<TEMPLATE
1271<p class="alert alert-danger">Error connecting to <a href="https://faucetbox.com">FaucetBOX.com API</a>. Either your hosting provider doesn't support external connections or FaucetBOX.com API is down. Send an email to <a href="mailto:support@faucetbox.com">support@faucetbox.com</a> if you need help.</p>
1272TEMPLATE;
1273
1274$reverse_proxy_changed_alert_template = <<<TEMPLATE
1275<p class="alert alert-danger"><b>This setting was automatically changed back to None, because people viewing your faucet without reverse proxy were detected</b>. Make sure your reverse proxy is configured correctly.</p>
1276TEMPLATE;
1277
1278$curl_warning_template = <<<TEMPLATE
1279<p class="alert alert-danger">cURL based connection failed, using legacy method. Please set <code>'disable_curl' => true,</code> in <code>config.php</code> file.</p>
1280TEMPLATE;
1281
1282$send_coins_success_template = <<<TEMPLATE
1283<p class="alert alert-success">You sent {{amount}} satoshi to <a href="https://faucetbox.com/check/{{address}}" target="_blank">{{address}}</a>.</p>
1284<script> $(document).ready(function(){ $('.nav-tabs a[href="#send-coins"]').tab('show'); }); </script>
1285TEMPLATE;
1286
1287$send_coins_error_template = <<<TEMPLATE
1288<p class="alert alert-danger">There was an error while sending {{amount}} satoshi to "{{address}}": <u>{{error}}</u></p>
1289<script> $(document).ready(function(){ $('.nav-tabs a[href="#send-coins"]').tab('show'); }); </script>
1290TEMPLATE;
1291
1292$missing_configs_template = <<<TEMPLATE
1293<div class="alert alert-warning">
1294<b>There are missing settings in your config.php file. That's probably because they were added in recent update.</b>
1295<:: missing_configs ::>
1296<hr>
1297</div>
1298TEMPLATE;
1299
1300$missing_config_template = <<<TEMPLATE
1301<hr>
1302 <ul>
1303 <li>Name: <:: config_name ::></li>
1304 <li>Default: <code>$<:: config_name ::> = <:: config_default ::>;</code></li>
1305 <li><:: config_description ::></li>
1306 </ul>
1307TEMPLATE;
1308
1309$template_updates_template = <<<TEMPLATE
1310<div class="alert alert-warning">
1311 <b>Your template file is out of date and won't work with this version of Faucet in a BOX. Here's what you have to do to fix that:</b>
1312 <:: template_updates ::>
1313<hr>
1314</div>
1315TEMPLATE;
1316
1317$template_update_template = <<<TEMPLATE
1318<hr>
1319 <ul>
1320 <li><:: message ::></li>
1321 </ul>
1322TEMPLATE;
1323
1324// ****************** END ADMIN TEMPLATES
1325
1326#reCaptcha template
1327$recaptcha_template = <<<TEMPLATE
1328<script src="https://www.google.com/recaptcha/api.js" async defer></script>
1329<div class="g-recaptcha" data-sitekey="<:: your_site_key ::>"></div>
1330<noscript>
1331 <div style="width: 302px; height: 352px;">
1332 <div style="width: 302px; height: 352px; position: relative;">
1333 <div style="width: 302px; height: 352px; position: absolute;">
1334 <iframe src="https://www.google.com/recaptcha/api/fallback?k=<:: your_site_key ::>"
1335 frameborder="0" scrolling="no"
1336 style="width: 302px; height:352px; border-style: none;">
1337 </iframe>
1338 </div>
1339 <div style="width: 250px; height: 80px; position: absolute; border-style: none;
1340 bottom: 21px; left: 25px; margin: 0px; padding: 0px; right: 25px;">
1341 <textarea id="g-recaptcha-response" name="g-recaptcha-response"
1342 class="g-recaptcha-response"
1343 style="width: 250px; height: 80px; border: 1px solid #c1c1c1;
1344 margin: 0px; padding: 0px; resize: none;" value="">
1345 </textarea>
1346 </div>
1347 </div>
1348 </div>
1349</noscript>
1350TEMPLATE;
1351
1352function checkOneclickUpdatePossible($response) {
1353 global $version;
1354
1355 $oneclick_update_possible = false;
1356 if(!empty($response['changelog'][$version]['hashes'])) {
1357 $hashes = $response['changelog'][$version]['hashes'];
1358 $oneclick_update_possible = class_exists("ZipArchive");
1359 foreach($hashes as $file => $hash) {
1360 if(strpos($file, 'templates/') === 0)
1361 continue;
1362 $oneclick_update_possible &=
1363 is_writable($file) &&
1364 sha1_file($file) === $hash;
1365 }
1366 }
1367 return $oneclick_update_possible;
1368}
1369
1370function setNewPass() {
1371 global $sql;
1372 $alphabet = str_split('qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890');
1373 $password = '';
1374 for($i = 0; $i < 15; $i++)
1375 $password .= $alphabet[array_rand($alphabet)];
1376 $hash = crypt($password);
1377 $sql->query("REPLACE INTO Faucetinabox_Settings VALUES ('password', '$hash')");
1378 return $password;
1379}
1380
1381function randHash($length) {
1382 $alphabet = str_split('qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890');
1383 $hash = '';
1384 for($i = 0; $i < $length; $i++) {
1385 $hash .= $alphabet[array_rand($alphabet)];
1386 }
1387 return $hash;
1388}
1389
1390// check if configured
1391try {
1392 $pass = $sql->query("SELECT `value` FROM `Faucetinabox_Settings` WHERE `name` = 'password'")->fetch();
1393} catch(PDOException $e) {
1394 $pass = null;
1395}
1396
1397function getIP() {
1398 global $sql;
1399 $type = $sql->query("SELECT `value` FROM `Faucetinabox_Settings` WHERE `name` = 'reverse_proxy'")->fetch();
1400 if (!$type) $type = array('none');
1401 switch ($type[0]) {
1402 case 'cloudflare':
1403 $ip = array_key_exists('HTTP_CF_CONNECTING_IP', $_SERVER) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : null;
1404 break;
1405 case 'incapsula':
1406 $ip = array_key_exists('HTTP_INCAP_CLIENT_IP', $_SERVER) ? $_SERVER['HTTP_INCAP_CLIENT_IP'] : null;
1407 break;
1408 default:
1409 $ip = $_SERVER['REMOTE_ADDR'];
1410 }
1411 if (empty($ip)) {
1412 $sql->query("UPDATE `Faucetinabox_Settings` SET `value` = 'none-auto' WHERE `name` = 'reverse_proxy' AND `value` <> 'none' LIMIT 1");
1413 return $_SERVER['REMOTE_ADDR'];
1414 }
1415 return $ip;
1416}
1417
1418function is_ssl(){
1419 if(isset($_SERVER['HTTPS'])){
1420 if('on' == strtolower($_SERVER['HTTPS']))
1421 return true;
1422 if('1' == $_SERVER['HTTPS'])
1423 return true;
1424 if(true == $_SERVER['HTTPS'])
1425 return true;
1426 }elseif(isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])){
1427 return true;
1428 }
1429 if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') {
1430 return true;
1431 }
1432 return false;
1433}
1434
1435function ipSubnetCheck ($ip, $network) {
1436 $network = explode("/", $network);
1437 $net = $network[0];
1438
1439 if(count($network) > 1) {
1440 $mask = $network[1];
1441 } else {
1442 $mask = 32;
1443 }
1444
1445 $net = ip2long ($net);
1446 $mask = ~((1 << (32 - $mask)) - 1);
1447
1448 $ip_net = $ip & $mask;
1449
1450 return ($ip_net == $net);
1451}
1452
1453function banned() {
1454 trigger_error("Banned: ".getIP());
1455 http_response_code(500);
1456 die();
1457}
1458
1459function suspicious($server, $comment) {
1460 if($server) {
1461 @file_get_contents($server."report/1/".urlencode(getIP())."/".urlencode($comment));
1462 }
1463}
1464
1465
1466if($pass) {
1467 if(array_key_exists('p', $_GET) && $_GET['p'] == 'logout')
1468 $_SESSION = array();
1469
1470 // check db updates
1471 $dbversion = $sql->query("SELECT `value` FROM `Faucetinabox_Settings` WHERE `name` = 'version'")->fetch();
1472 if($dbversion) {
1473 $dbversion = intval($dbversion[0]);
1474 } else {
1475 $dbversion = -1;
1476 }
1477 foreach($db_updates as $v => $update) {
1478 if($v > $dbversion) {
1479 foreach($update as $query) {
1480 $sql->exec($query);
1481 }
1482 }
1483 }
1484 if($dbversion < 17) {
1485 // dogecoin changed from satoshi to doge
1486 // better clear rewards...
1487 $c = $sql->query("SELECT `value` FROM `Faucetinabox_Settings` WHERE `name` = 'currency'")->fetch();
1488 if($c[0] == 'DOGE')
1489 $sql->exec("UPDATE `Faucetinabox_Settings` SET `value` = '' WHERE name = 'rewards'");
1490 }
1491 if(intval($version) > intval($dbversion)) {
1492 $q = $sql->prepare("UPDATE `Faucetinabox_Settings` SET `value` = ? WHERE `name` = 'version'");
1493 $q->execute(array($version));
1494 }
1495
1496 $security_settings = array();
1497 $q = $sql->query("SELECT `name`, `value` FROM `Faucetinabox_Settings` WHERE `name` in ('ip_check_server', 'ip_ban_list', 'hostname_ban_list', 'address_ban_list')");
1498 while($row = $q->fetch()) {
1499 if(stripos($row["name"], "_list") !== false) {
1500 $security_settings[$row["name"]] = array();
1501 if(preg_match_all("/[^,;\s]+/", $row["value"], $matches)) {
1502 foreach($matches[0] as $m) {
1503 $security_settings[$row["name"]][] = $m;
1504 }
1505 }
1506 } else {
1507 $security_settings[$row["name"]] = $row["value"];
1508 }
1509 }
1510
1511 if(!empty($_POST["mmc"])) {
1512 $_SESSION["mouse_movement_detected"] = true;
1513 die();
1514 }
1515
1516 if($_SERVER["REQUEST_METHOD"] == "POST") {
1517 if($security_settings["ip_check_server"]) {
1518 if(!preg_match("#/$#", $security_settings["ip_check_server"])) {
1519 $security_settings["ip_check_server"] .= "/";
1520 }
1521 }
1522
1523 // banning
1524 $ip = ip2long(getIP());
1525 if($ip) { // only ipv4 supported here
1526 foreach($security_settings["ip_ban_list"] as $ban) {
1527 if(ipSubnetCheck($ip, $ban)) {
1528 banned();
1529 }
1530 }
1531 }
1532
1533 if($security_settings["ip_check_server"]) {
1534
1535 $hostnames = @file_get_contents($security_settings["ip_check_server"].getIP());
1536 $hostnames = json_decode($hostnames);
1537
1538 if($hostnames && property_exists($hostnames, "status") && $hostnames->status == 200) {
1539 if(property_exists($hostnames, 'suggestion') && $hostnames->suggestion == "deny") {
1540 banned();
1541 }
1542
1543 if(property_exists($hostnames, 'hostnames')) {
1544 foreach($security_settings["hostname_ban_list"] as $ban) {
1545 foreach($hostnames->hostnames as $hostname) {
1546 if(stripos($hostname, $ban) !== false) {
1547 banned();
1548 }
1549 }
1550 }
1551 }
1552
1553 }
1554 }
1555 $fake_address_input_used = false;
1556 if(!empty($_POST["address"])) {
1557 $fake_address_input_used = true;
1558 }
1559 }
1560
1561
1562 if(!$disable_admin_panel && array_key_exists('p', $_GET) && $_GET['p'] == 'admin') {
1563 $invalid_key = false;
1564 if (array_key_exists('password', $_POST)) {
1565 if ($pass[0] == crypt($_POST['password'], $pass[0])) {
1566 $_SESSION["$session_prefix-logged_in"] = true;
1567 header("Location: ?p=admin&session_check=0");
1568 die();
1569 } else {
1570 $admin_login_template = $login_error_template.$admin_login_template;
1571 }
1572 }
1573 if (array_key_exists("session_check", $_GET)) {
1574 if (array_key_exists("$session_prefix-logged_in", $_SESSION)) {
1575 header("Location: ?p=admin");
1576 die();
1577 } else {
1578 //show alert on login screen
1579 $admin_login_template = $session_error_template.$admin_login_template;
1580 }
1581 }
1582
1583 if(array_key_exists("$session_prefix-logged_in", $_SESSION)) { // logged in to admin page
1584
1585 //ajax
1586 if (array_key_exists("action", $_POST)) {
1587
1588 header("Content-type: application/json");
1589
1590 $response = ["status" => 404];
1591
1592 switch ($_POST["action"]) {
1593 case "check_referrals":
1594
1595 $referral = array_key_exists("referral", $_POST) ? trim($_POST["referral"]) : "";
1596
1597 $response["status"] = 200;
1598 $response["addresses"] = [];
1599
1600 if (strlen($referral) > 0) {
1601
1602 $q = $sql->prepare("SELECT `a`.`address`, `r`.`address` FROM `Faucetinabox_Refs` `r` LEFT JOIN `Faucetinabox_Addresses` `a` ON `r`.`id` = `a`.`ref_id` WHERE `r`.`address` LIKE ? ORDER BY `a`.`last_used` DESC");
1603 $q->execute(["%".$referral."%"]);
1604 while ($row = $q->fetch()) {
1605 $response["addresses"][] = [
1606 "address" => $row[0],
1607 "referral" => $row[1],
1608 ];
1609 }
1610
1611 }
1612
1613 break;
1614 }
1615
1616 die(json_encode($response));
1617
1618 }
1619
1620 if (array_key_exists('task', $_POST) && $_POST['task'] == 'oneclick-update') {
1621 function recurse_copy($copy_as_new,$src,$dst) {
1622 $dir = opendir($src);
1623 @mkdir($dst);
1624 while(false !== ( $file = readdir($dir)) ) {
1625 if (( $file != '.' ) && ( $file != '..' )) {
1626 if ( is_dir($src . '/' . $file) ) {
1627 recurse_copy($copy_as_new, $src . '/' . $file,$dst . '/' . $file);
1628 }
1629 else {
1630 $dstfile = $dst.'/'.$file;
1631 if(in_array(realpath($dstfile), $copy_as_new))
1632 $dstfile .= ".new";
1633 if(!copy($src . '/' . $file,$dstfile)) {
1634 return false;
1635 }
1636 }
1637 }
1638 }
1639 closedir($dir);
1640 return true;
1641 }
1642 function rrmdir($dir) {
1643 if (is_dir($dir)) {
1644 $objects = scandir($dir);
1645 foreach ($objects as $object) {
1646 if ($object != "." && $object != "..") {
1647 if (filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
1648 }
1649 }
1650 reset($objects);
1651 rmdir($dir);
1652 }
1653 }
1654
1655 ini_set('display_errors', true);
1656 error_reporting(-1);
1657 $fb = new FaucetBOX(null, null, $connection_options);
1658 $response = $fb->fiabVersionCheck();
1659 if(empty($response['version']) || $response['version'] == $version || !checkOneclickUpdatePossible($response)) {
1660 header("Location: ?p=admin&update_status=fail");
1661 die();
1662 }
1663
1664 $url = $response["url"];
1665 if($url[0] == '/') $url = "https:$url";
1666 $url .= "?update=auto";
1667
1668 if(!file_put_contents('update.zip', fopen($url, 'rb'))) {
1669 header("Location: ?p=admin&update_status=fail");
1670 die();
1671 }
1672
1673 $zip = new ZipArchive();
1674 if(!$zip->open('update.zip')) {
1675 unlink('update.zip');
1676 header("Location: ?p=admin&update_status=fail");
1677 die();
1678 }
1679
1680 if(!$zip->extractTo('./')) {
1681 unlink('update.zip');
1682 header("Location: ?p=admin&update_status=fail");
1683 die();
1684 }
1685
1686 $dir = trim($zip->getNameIndex(0), '/');
1687 $zip->close();
1688 unlink('update.zip');
1689 unlink("$dir/config.php");
1690
1691 $modified_files = [];
1692 foreach($response['changelog'][$version]['hashes'] as $file => $hash) {
1693 if(strpos($file, 'templates/') === 0 &&
1694 sha1_file($file) !== $hash
1695 ) {
1696 $modified_files[] = realpath($file);
1697 }
1698 }
1699 if(!recurse_copy($modified_files, $dir, '.')) {
1700 header("Location: ?p=admin&update_status=fail");
1701 die();
1702 }
1703 rrmdir($dir);
1704 header("Location: ?p=admin&update_status=success&new_files=".count($modified_files));
1705 die();
1706 }
1707
1708 if (
1709 array_key_exists("update_status", $_GET) &&
1710 in_array($_GET["update_status"], ["success", "fail"])
1711 ) {
1712 if ($_GET["update_status"] == "success") {
1713 $oneclick_update_alert = $oneclick_update_success_template;
1714 } else {
1715 $oneclick_update_alert = $oneclick_update_fail_template;
1716 }
1717 } else {
1718 $oneclick_update_alert = "";
1719 }
1720
1721 if (array_key_exists("encoded_data", $_POST)) {
1722 $data = base64_decode($_POST["encoded_data"]);
1723 if ($data) {
1724 parse_str($data, $tmp);
1725 $_POST = array_merge($_POST, $tmp);
1726 }
1727 }
1728
1729 if(array_key_exists('get_options', $_POST)) {
1730 if(file_exists("templates/{$_POST["get_options"]}/setup.php")) {
1731 require_once("templates/{$_POST["get_options"]}/setup.php");
1732 die(getTemplateOptions($sql, $_POST['get_options']));
1733 } else {
1734 die('<p>No template defined options available.</p>');
1735 }
1736 } else if(
1737 array_key_exists("reset", $_POST) &&
1738 array_key_exists("factory_reset_confirm", $_POST) &&
1739 $_POST["factory_reset_confirm"] == "on"
1740 ) {
1741 $sql->exec("DELETE FROM Faucetinabox_Settings WHERE name NOT LIKE '%key%' AND name != 'password'");
1742 $sql->exec($default_data_query);
1743 }
1744 $q = $sql->prepare("SELECT value FROM Faucetinabox_Settings WHERE name = ?");
1745 $q->execute(array('apikey'));
1746 $apikey = $q->fetch();
1747 $apikey = $apikey[0];
1748 $q->execute(array('currency'));
1749 $currency = $q->fetch();
1750 $currency = $currency[0];
1751 $fb = new FaucetBOX($apikey, $currency, $connection_options);
1752 $currencies = $fb->getCurrencies();
1753 $connection_error = '';
1754 $curl_warning = '';
1755 $missing_configs_info = '';
1756 if(!empty($missing_configs)) {
1757 $list = '';
1758 foreach($missing_configs as $missing_config) {
1759 $list .= str_replace(array("<:: config_name ::>", "<:: config_default ::>", "<:: config_description ::>"), array($missing_config['name'], $missing_config['default'], $missing_config['desc']), $missing_config_template);
1760 }
1761 $missing_configs_info = str_replace("<:: missing_configs ::>", $list, $missing_configs_template);
1762 }
1763 if($fb->curl_warning) {
1764 $curl_warning = $curl_warning_template;
1765 }
1766 if(!$currencies) {
1767 $currencies = array('BTC', 'LTC', 'DOGE', 'PPC', 'XPM', 'DASH');
1768 if($fb->communication_error) {
1769 $connection_error = $connection_error_template;
1770 }
1771 }
1772 $send_coins_message = '';
1773 if(array_key_exists('send_coins', $_POST)) {
1774
1775 $amount = array_key_exists('send_coins_amount', $_POST) ? intval($_POST['send_coins_amount']) : 0;
1776 $address = array_key_exists('send_coins_address', $_POST) ? trim($_POST['send_coins_address']) : '';
1777
1778 $fb = new FaucetBOX($apikey, $currency, $connection_options);
1779 $ret = $fb->send($address, $amount);
1780
1781 if ($ret['success']) {
1782 $send_coins_message = str_replace(array('{{amount}}','{{address}}'), array($amount,$address), $send_coins_success_template);
1783 } else {
1784 $send_coins_message = str_replace(array('{{amount}}','{{address}}','{{error}}'), array($amount,$address,$ret['message']), $send_coins_error_template);
1785 }
1786
1787 }
1788 $changes_saved = "";
1789 $nastyhosts_not_allowed_alert = "";
1790 if(array_key_exists('save_settings', $_POST)) {
1791 $currency = $_POST['currency'];
1792 $fb = new FaucetBOX($_POST['apikey'], $currency, $connection_options);
1793 $ret = $fb->getBalance();
1794
1795 if($ret['status'] == 403) {
1796 $invalid_key = true;
1797 } elseif($ret['status'] == 405) {
1798 $sql->query("UPDATE Faucetinabox_Settings SET `value` = 0 WHERE name = 'balance'");
1799 } elseif(array_key_exists('balance', $ret)) {
1800 $q = $sql->prepare("UPDATE Faucetinabox_Settings SET `value` = ? WHERE name = 'balance'");
1801 if($currency != 'DOGE')
1802 $q->execute(array($ret['balance']));
1803 else
1804 $q->execute(array($ret['balance_bitcoin']));
1805 }
1806
1807 $q = $sql->prepare("INSERT IGNORE INTO Faucetinabox_Settings (`name`, `value`) VALUES (?, ?)");
1808 $template = $_POST["template"];
1809 preg_match_all('/\$data\[([\'"])(custom_(?:(?!\1).)*)\1\]/', file_get_contents("templates/$template/index.php"), $matches);
1810 foreach($matches[2] as $box)
1811 $q->execute(array("{$box}_$template", ''));
1812
1813
1814 if (array_key_exists("ip_check_server", $_POST) && !empty($_POST["ip_check_server"])) {
1815
1816 $hostnames = @file_get_contents($_POST["ip_check_server"].getIP());
1817 $hostnames = json_decode($hostnames);
1818
1819 if ($hostnames && property_exists($hostnames, "status") && $hostnames->status == 200) {
1820 if (property_exists($hostnames, 'suggestion') && $hostnames->suggestion == "deny") {
1821 $nastyhosts_not_allowed_alert = $nastyhosts_not_allowed_template;
1822 $_POST["ip_check_server"] = "";
1823 }
1824 }
1825
1826 }
1827
1828
1829 $q = $sql->prepare("UPDATE Faucetinabox_Settings SET value = ? WHERE name = ?");
1830 $ipq = $sql->prepare("INSERT INTO Faucetinabox_Pages (url_name, name, html) VALUES (?, ?, ?)");
1831 $sql->exec("DELETE FROM Faucetinabox_Pages");
1832 foreach($_POST as $k => $v) {
1833 if($k == 'apikey' && $invalid_key)
1834 continue;
1835 if($k == 'pages') {
1836 foreach($_POST['pages'] as $p) {
1837 $url_name = strtolower(preg_replace("/[^A-Za-z0-9_\-]/", '', $p["name"]));
1838 $i = 0;
1839 $success = false;
1840 while(!$success) {
1841 try {
1842 if($i)
1843 $ipq->execute(array($url_name.'-'.$i, $p['name'], $p['html']));
1844 else
1845 $ipq->execute(array($url_name, $p['name'], $p['html']));
1846 $success = true;
1847 } catch(PDOException $e) {
1848 $i++;
1849 }
1850 }
1851 }
1852 continue;
1853 }
1854 $q->execute(array($v, $k));
1855 }
1856 if (!array_key_exists('block_adblock', $_POST)) $q->execute(array('', 'block_adblock'));
1857
1858 $changes_saved = $changes_saved_template;
1859 }
1860 $page = str_replace('<:: content ::>', $admin_template, $master_template);
1861 $query = $sql->query("SELECT name, value FROM Faucetinabox_Settings");
1862 while($row = $query->fetch()) {
1863 if($row[0] == 'template') {
1864 if(file_exists("templates/{$row[1]}/index.php")) {
1865 $current_template = $row[1];
1866 } else {
1867 $templates = glob("templates/*");
1868 if($templates)
1869 $current_template = substr($templates[0], strlen('templates/'));
1870 else
1871 die(str_replace("<:: content ::>", "<div class='alert alert-danger' role='alert'>No templates found! Please reinstall your faucet.</div>", $master_template));
1872 }
1873 } else {
1874 if ($row[0] == 'reverse_proxy') {
1875 if ($row[1] == 'none-auto') {
1876 $reverse_proxy_changed_alert = $reverse_proxy_changed_alert_template;
1877 $row[1] = 'none';
1878 } else {
1879 $reverse_proxy_changed_alert = '';
1880 }
1881 $page = str_replace('<:: reverse_proxy_changed_alert ::>', $reverse_proxy_changed_alert, $page);
1882 }
1883 if($row[0] == 'block_adblock') {
1884 $row[1] = $row[1] == 'on' ? 'checked' : '';
1885 }
1886 $page = str_replace("<:: {$row[0]} ::>", $row[1], $page);
1887 }
1888 }
1889
1890
1891 $templates = '';
1892 foreach(glob("templates/*") as $template) {
1893 $template = basename($template);
1894 if($template == $current_template) {
1895 $templates .= "<option selected>$template</option>";
1896 } else {
1897 $templates .= "<option>$template</option>";
1898 }
1899 }
1900 $page = str_replace('<:: templates ::>', $templates, $page);
1901 $page = str_replace('<:: current_template ::>', $current_template, $page);
1902
1903
1904 if(file_exists("templates/{$current_template}/setup.php")) {
1905 require_once("templates/{$current_template}/setup.php");
1906 $page = str_replace('<:: template_options ::>', getTemplateOptions($sql, $current_template), $page);
1907 } else {
1908 $page = str_replace('<:: template_options ::>', '<p>No template defined options available.</p>', $page);
1909 }
1910
1911 $template_string = file_get_contents("templates/{$current_template}/index.php");
1912 $template_updates_info = '';
1913 foreach($template_updates as $update) {
1914 if(!preg_match($update["test"], $template_string)) {
1915 $template_updates_info .= str_replace("<:: message ::>", $update["message"], $template_update_template);
1916 }
1917 }
1918 if(!empty($template_updates_info)) {
1919 $template_updates_info = str_replace("<:: template_updates ::>", $template_updates_info, $template_updates_template);
1920 }
1921
1922 $q = $sql->query("SELECT name, html FROM Faucetinabox_Pages ORDER BY id");
1923 $pages = '';
1924 $pages_nav = '';
1925 $i = 1;
1926 while($userpage = $q->fetch()) {
1927 $html = htmlspecialchars($userpage['html']);
1928 $name = htmlspecialchars($userpage['name']);
1929 $pages .= str_replace(array('<:: i ::>', '<:: page_name ::>', '<:: html ::>'),
1930 array($i, $name, $html), $page_form_template);
1931 $pages_nav .= str_replace('<:: i ::>', $i, $page_nav_template);
1932 ++$i;
1933 }
1934 $page = str_replace('<:: pages ::>', $pages, $page);
1935 $page = str_replace('<:: pages_nav ::>', $pages_nav, $page);
1936 $currencies_select = "";
1937 foreach($currencies as $c) {
1938 if($currency == $c)
1939 $currencies_select .= "<option value='$c' selected>$c</option>";
1940 else
1941 $currencies_select .= "<option value='$c'>$c</option>";
1942 }
1943 $page = str_replace('<:: currency ::>', $currency, $page);
1944 $page = str_replace('<:: currencies ::>', $currencies_select, $page);
1945
1946
1947 if($invalid_key)
1948 $page = str_replace('<:: invalid_key ::>', $invalid_key_error_template, $page);
1949 else
1950 $page = str_replace('<:: invalid_key ::>', '', $page);
1951
1952 $page = str_replace('<:: page_form_template ::>',
1953 json_encode($page_form_template),
1954 $page);
1955 $page = str_replace('<:: page_nav_template ::>',
1956 json_encode($page_nav_template),
1957 $page);
1958
1959 $new_files = [];
1960 foreach (new RecursiveIteratorIterator (new RecursiveDirectoryIterator ('templates')) as $file) {
1961 $file = $file->getPathname();
1962 if(substr($file, -4) == ".new") {
1963 $new_files[] = $file;
1964 }
1965 }
1966
1967 if($new_files) {
1968 $new_files = implode("\n", array_map(function($v) { return "<li>$v</li>"; }, $new_files));
1969 $new_files = str_replace("<:: new_files ::>", $new_files, $new_files_template);
1970 } else {
1971 $new_files = "";
1972 }
1973 $page = str_replace("<:: new_files ::>", $new_files, $page);
1974
1975 $response = $fb->fiabVersionCheck();
1976 $oneclick_update_possible = checkOneclickUpdatePossible($response);
1977 if(!$connection_error && $response['version'] && $version < intval($response["version"])) {
1978 $page = str_replace('<:: version_check ::>', $new_version_template, $page);
1979 $changelog = '';
1980 foreach($response['changelog'] as $v => $changes) {
1981 $changelog_entries = array_map(function($entry) {
1982 return "<li>$entry</li>";
1983 }, $changes['changelog']);
1984 $changelog_entries = implode("", $changelog_entries);
1985 if(intval($v) > $version) {
1986 $changelog .= "<p>Changes in r$v (${changes['released']}): <ul>${changelog_entries}</ul></p>";
1987 }
1988 }
1989 $page = str_replace(array('<:: url ::>', '<:: version ::>', '<:: changelog ::>'), array($response['url'], $response['version'], $changelog), $page);
1990 if($oneclick_update_possible) {
1991 $page = str_replace('<:: oneclick_update_button ::>', $oneclick_update_button_template, $page);
1992 } else {
1993 $page = str_replace('<:: oneclick_update_button ::>', '', $page);
1994 }
1995 } else {
1996 $page = str_replace('<:: version_check ::>', '', $page);
1997 }
1998 $page = str_replace('<:: connection_error ::>', $connection_error, $page);
1999 $page = str_replace('<:: curl_warning ::>', $curl_warning, $page);
2000 $page = str_replace('<:: send_coins_message ::>', $send_coins_message, $page);
2001 $page = str_replace('<:: missing_configs ::>', $missing_configs_info, $page);
2002 $page = str_replace('<:: template_updates ::>', $template_updates_info, $page);
2003 $page = str_replace('<:: changes_saved ::>', $changes_saved, $page);
2004 $page = str_replace('<:: oneclick_update_alert ::>', $oneclick_update_alert, $page);
2005 $page = str_replace('<:: nastyhosts_not_allowed ::>', $nastyhosts_not_allowed_alert, $page);
2006 die($page);
2007 } else {
2008 // requested admin page without session
2009 $page = str_replace('<:: content ::>', $admin_login_template, $master_template);
2010 die($page);
2011 }
2012 } elseif(!$disable_admin_panel && array_key_exists('p', $_GET) && $_GET['p'] == 'password-reset') {
2013 $error = "";
2014 if(array_key_exists('dbpass', $_POST)) {
2015 if($_POST['dbpass'] == $dbpass) {
2016 $password = setNewPass();
2017 $page = str_replace('<:: content ::>', $pass_template, $master_template);
2018 $page = str_replace('<:: password ::>', $password, $page);
2019 die($page);
2020 } else {
2021 $error = "<p class='alert alert-danger' role='alert'>Wrong database password</p>";
2022 }
2023 }
2024 $page = str_replace('<:: content ::>', $error.$pass_reset_template, $master_template);
2025 die($page);
2026 } else {
2027 // show main page
2028 $q = $sql->query("SELECT value FROM Faucetinabox_Settings WHERE name = 'template'");
2029 $template = $q->fetch();
2030 $template = $template[0];
2031 if(!file_exists("templates/{$template}/index.php")) {
2032 $templates = glob("templates/*");
2033 if($templates)
2034 $template = substr($templates[0], strlen("templates/"));
2035 else
2036 die(str_replace('<:: content ::>', "<div class='alert alert-danger' role='alert'>No templates found!</div>", $master_template));
2037 }
2038
2039 if(array_key_exists("HTTPS", $_SERVER) && $_SERVER["HTTPS"])
2040 $protocol = "https://";
2041 else
2042 $protocol = "http://";
2043
2044 if (array_key_exists('address_input_name', $_SESSION) && array_key_exists($_SESSION['address_input_name'], $_POST)) {
2045 $_POST['address'] = $_POST[$_SESSION['address_input_name']];
2046 } else {
2047 if($display_errors && $_SERVER['REQUEST_METHOD'] == "POST") {
2048 if(array_key_exists('address_input_name', $_SESSION)) {
2049 trigger_error("Post request, but session is invalid.");
2050 } else {
2051 trigger_error("Post request, but invalid address input name.");
2052 }
2053 }
2054 unset($_POST['address']);
2055 }
2056
2057
2058 $data = array(
2059 "paid" => false,
2060 "disable_admin_panel" => $disable_admin_panel,
2061 "address" => "",
2062 "captcha_valid" => !array_key_exists('address', $_POST),
2063 "captcha" => false,
2064 "enabled" => false,
2065 "error" => false,
2066 "reflink" => $protocol.$_SERVER['HTTP_HOST'].strtok($_SERVER['REQUEST_URI'], '?').'?r='
2067 );
2068 if(array_key_exists('address', $_POST)) {
2069 $data["reflink"] .= $_POST['address'];
2070 } else if (array_key_exists('address', $_COOKIE)) {
2071 $data["reflink"] .= $_COOKIE['address'];
2072 $data["address"] = $_COOKIE['address'];
2073 } else {
2074 $data["reflink"] .= 'Your_Address';
2075 }
2076
2077
2078 $q = $sql->query("SELECT name, value FROM Faucetinabox_Settings WHERE name <> 'password'");
2079
2080 while($row = $q->fetch()) {
2081 $data[$row[0]] = $row[1];
2082 }
2083
2084 if(time() - $data['last_balance_check'] > 60*10) {
2085 $fb = new FaucetBOX($data['apikey'], $data['currency'], $connection_options);
2086 $ret = $fb->getBalance();
2087 if(array_key_exists('balance', $ret)) {
2088 if($data['currency'] != 'DOGE')
2089 $balance = $ret['balance'];
2090 else
2091 $balance = $ret['balance_bitcoin'];
2092 $q = $sql->prepare("UPDATE Faucetinabox_Settings SET value = ? WHERE name = ?");
2093 $q->execute(array(time(), 'last_balance_check'));
2094 $q->execute(array($balance, 'balance'));
2095 $data['balance'] = $balance;
2096 $data['last_balance_check'] = time();
2097 }
2098 }
2099
2100 $data['unit'] = 'satoshi';
2101 if($data["currency"] == 'DOGE')
2102 $data["unit"] = 'DOGE';
2103
2104
2105 #MuliCaptcha: Firstly check chosen captcha system
2106 $captcha = array('available' => array(), 'selected' => null);
2107 if ($data['solvemedia_challenge_key'] && $data['solvemedia_verification_key'] && $data['solvemedia_auth_key']) {
2108 $captcha['available'][] = 'SolveMedia';
2109 }
2110 if ($data['recaptcha_public_key'] && $data['recaptcha_private_key']) {
2111 $captcha['available'][] = 'reCaptcha';
2112 }
2113 if ($data['ayah_publisher_key'] && $data['ayah_scoring_key']) {
2114 $captcha['available'][] = 'AreYouAHuman';
2115 }
2116 if ($data['funcaptcha_public_key'] && $data['funcaptcha_private_key']) {
2117 $captcha['available'][] = 'FunCaptcha';
2118 }
2119
2120 #MuliCaptcha: Secondly check if user switched captcha or choose default
2121 if (array_key_exists('cc', $_GET) && in_array($_GET['cc'], $captcha['available'])) {
2122 $captcha['selected'] = $captcha['available'][array_search($_GET['cc'], $captcha['available'])];
2123 $_SESSION["$session_prefix-selected_captcha"] = $captcha['selected'];
2124 } elseif (array_key_exists("$session_prefix-selected_captcha", $_SESSION) && in_array($_SESSION["$session_prefix-selected_captcha"], $captcha['available'])) {
2125 $captcha['selected'] = $_SESSION["$session_prefix-selected_captcha"];
2126 } else {
2127 if($captcha['available'])
2128 $captcha['selected'] = $captcha['available'][0];
2129 if (in_array($data['default_captcha'], $captcha['available'])) {
2130 $captcha['selected'] = $data['default_captcha'];
2131 } else if($captcha['available']) {
2132 $captcha['selected'] = $captcha['available'][0];
2133 }
2134 }
2135
2136
2137
2138 #MuliCaptcha: And finally handle chosen captcha system
2139 switch ($captcha['selected']) {
2140 case 'SolveMedia':
2141 require_once("libs/solvemedialib.php");
2142 $data["captcha"] = solvemedia_get_html($data["solvemedia_challenge_key"], null, is_ssl());
2143 if (array_key_exists('address', $_POST)) {
2144 $resp = solvemedia_check_answer(
2145 $data['solvemedia_verification_key'],
2146 getIP(),
2147 (array_key_exists('adcopy_challenge', $_POST) ? $_POST['adcopy_challenge'] : ''),
2148 (array_key_exists('adcopy_response', $_POST) ? $_POST['adcopy_response'] : ''),
2149 $data["solvemedia_auth_key"]
2150 );
2151 $data["captcha_valid"] = $resp->is_valid;
2152 }
2153 break;
2154 case 'reCaptcha':
2155 $data["captcha"] = str_replace('<:: your_site_key ::>', $data["recaptcha_public_key"], $recaptcha_template);
2156 if (array_key_exists('address', $_POST)) {
2157 $url = 'https://www.google.com/recaptcha/api/siteverify?secret='.$data["recaptcha_private_key"].'&response='.(array_key_exists('g-recaptcha-response', $_POST) ? $_POST["g-recaptcha-response"] : '').'&remoteip='.getIP();
2158 $resp = json_decode(file_get_contents($url), true);
2159 $data['captcha_valid'] = $resp['success'];
2160 }
2161 break;
2162 case 'AreYouAHuman':
2163 require_once("libs/ayahlib.php");
2164 $ayah = new AYAH(array(
2165 'publisher_key' => $data['ayah_publisher_key'],
2166 'scoring_key' => $data['ayah_scoring_key'],
2167 'web_service_host' => 'ws.areyouahuman.com',
2168 'debug_mode' => false,
2169 'use_curl' => !($connection_options['disable_curl'])
2170 ));
2171 $data['captcha'] = $ayah->getPublisherHTML();
2172 if (array_key_exists('address', $_POST)) {
2173 $score = $ayah->scoreResult();
2174 $data['captcha_valid'] = $score;
2175 }
2176 break;
2177 case 'FunCaptcha':
2178 require_once("libs/funcaptcha.php");
2179 $funcaptcha = new FUNCAPTCHA();
2180
2181 $data["captcha"] = $funcaptcha->getFunCaptcha($data["funcaptcha_public_key"]);
2182
2183 if (array_key_exists('address', $_POST)) {
2184 $data['captcha_valid'] = $funcaptcha->checkResult($data["funcaptcha_private_key"]);
2185 }
2186 break;
2187 }
2188
2189 $data['captcha_info'] = $captcha;
2190
2191 if($data['captcha'] && $data['apikey'] && $data['rewards'])
2192 $data['enabled'] = true;
2193
2194
2195 // check if ip eligible
2196 $q = $sql->prepare("SELECT TIMESTAMPDIFF(MINUTE, last_used, CURRENT_TIMESTAMP()) FROM Faucetinabox_IPs WHERE ip = ?");
2197 $q->execute(array(getIP()));
2198 if ($time = $q->fetch()) {
2199 $time = intval($time[0]);
2200 $required = intval($data['timer']);
2201 $data['time_left'] = ($required-$time).' minutes';
2202 $data['eligible'] = $time >= intval($data['timer']);
2203 } else {
2204 $data["eligible"] = true;
2205 }
2206
2207 $rewards = explode(',', $data['rewards']);
2208 $total_weight = 0;
2209 $nrewards = array();
2210 foreach($rewards as $reward) {
2211 $reward = explode("*", trim($reward));
2212 if(count($reward) < 2) {
2213 $reward[1] = $reward[0];
2214 $reward[0] = 1;
2215 }
2216 $total_weight += intval($reward[0]);
2217 $nrewards[] = $reward;
2218 }
2219 $rewards = $nrewards;
2220 if(count($rewards) > 1) {
2221 $possible_rewards = array();
2222 foreach($rewards as $r) {
2223 $chance_per = 100 * $r[0]/$total_weight;
2224 if($chance_per < 0.1)
2225 $chance_per = '< 0.1%';
2226 else
2227 $chance_per = round(floor($chance_per*10)/10, 1).'%';
2228
2229 $possible_rewards[] = $r[1]." ($chance_per)";
2230 }
2231 } else {
2232 $possible_rewards = array($rewards[0][1]);
2233 }
2234
2235 $data['address_eligible'] = true;
2236
2237 if (array_key_exists('address', $_POST) &&
2238 $data['captcha_valid'] &&
2239 $data['enabled'] &&
2240 $data['eligible']
2241 ) {
2242
2243 $q = $sql->prepare("SELECT TIMESTAMPDIFF(MINUTE, last_used, CURRENT_TIMESTAMP()) FROM Faucetinabox_Addresses WHERE `address` = ?");
2244 $q->execute(array(trim($_POST['address'])));
2245 if ($time = $q->fetch()) {
2246 $time = intval($time[0]);
2247 $required = intval($data['timer']);
2248 $data['time_left'] = ($required-$time).' minutes';
2249 $eligible = $time >= intval($data['timer']);
2250 } else {
2251 $eligible = true;
2252 }
2253 $data['address_eligible'] = $eligible;
2254 if($eligible) {
2255 $r = mt_rand()/mt_getrandmax();
2256 $t = 0;
2257 foreach($rewards as $reward) {
2258 $t += intval($reward[0])/$total_weight;
2259 if($t > $r) {
2260 break;
2261 }
2262 }
2263
2264 if (strpos($reward[1], '-') !== false) {
2265 $reward_range = explode('-', $reward[1]);
2266 $from = floatval($reward_range[0]);
2267 $to = floatval($reward_range[1]);
2268 $reward = mt_rand($from, $to);
2269 } else {
2270 $reward = floatval($reward[1]);
2271 }
2272 if($data["currency"] == "DOGE")
2273 $reward = $reward * 100000000;
2274
2275 $q = $sql->prepare("SELECT balance FROM Faucetinabox_Refs WHERE address = ?");
2276 $q->execute(array(trim($_POST["address"])));
2277 if($b = $q->fetch()) {
2278 $refbalance = floatval($b[0]);
2279 } else {
2280 $refbalance = 0;
2281 }
2282 $fb = new FaucetBOX($data["apikey"], $data["currency"], $connection_options);
2283 $address = trim($_POST["address"]);
2284 if (empty($address)) {
2285 $ret = array(
2286 "success" => false,
2287 "message" => "Invalid address.",
2288 "html" => "<div class=\"alert alert-danger\">Invalid address.</div>"
2289 );
2290 } else if (in_array($address, $security_settings["address_ban_list"])) {
2291 $ret = array(
2292 "success" => false,
2293 "message" => "Unknown error.",
2294 "html" => "<div class=\"alert alert-danger\">Unknown error.</div>"
2295 );
2296 } else {
2297 $ret = $fb->send($address, $reward);
2298 }
2299 if($ret["success"] && $refbalance > 0)
2300 $ret = $fb->sendReferralEarnings(trim($_POST["address"]), $refbalance);
2301 if($ret['success']) {
2302 setcookie('address', trim($_POST['address']), time() + 60*60*24*60);
2303 if(array_key_exists('balance', $ret)) {
2304 $q = $sql->prepare("UPDATE Faucetinabox_Settings SET `value` = ? WHERE `name` = 'balance'");
2305
2306 if($data['unit'] == 'satoshi')
2307 $data['balance'] = $ret['balance'];
2308 else
2309 $data['balance'] = $ret['balance_bitcoin'];
2310 $q->execute(array($data['balance']));
2311 }
2312
2313 // handle refs
2314 // deduce balance
2315 $q = $sql->prepare("UPDATE Faucetinabox_Refs SET balance = balance - ? WHERE address = ?");
2316 $q->execute(array($refbalance, trim($_POST['address'])));
2317 // add balance
2318 if(array_key_exists('r', $_GET) && trim($_GET['r']) != trim($_POST["address"])) {
2319 $q = $sql->prepare("INSERT IGNORE INTO Faucetinabox_Refs (address) VALUES (?)");
2320 $q->execute(array(trim($_GET["r"])));
2321 $q = $sql->prepare("INSERT IGNORE INTO Faucetinabox_Addresses (`address`, `ref_id`, `last_used`) VALUES (?, (SELECT id FROM Faucetinabox_Refs WHERE address = ?), CURRENT_TIMESTAMP())");
2322 $q->execute(array(trim($_POST['address']), trim($_GET['r'])));
2323 }
2324 $refamount = floatval($data['referral'])*$reward/100;
2325 $q = $sql->prepare("SELECT address FROM Faucetinabox_Refs WHERE id = (SELECT ref_id FROM Faucetinabox_Addresses WHERE address = ?)");
2326 $q->execute(array(trim($_POST['address'])));
2327 if($ref = $q->fetch()) {
2328 if(!in_array(trim($ref[0]), $security_settings['address_ban_list'])) {
2329 $fb->sendReferralEarnings(trim($ref[0]), $refamount);
2330 }
2331 }
2332
2333 if($refbalance > 0) {
2334 $data['paid'] = '<div class="alert alert-success">'.htmlspecialchars($reward).' '.$unit.' + '.htmlspecialchars($refbalance).' '.$unit.' for referrals was sent to <a target="_blank" href="https://faucetbox.com/check/'.rawurlencode(trim($_POST["address"])).'">your FaucetBOX.com address</a>.</div>';
2335 } else {
2336 if($data['unit'] == 'satoshi')
2337 $data['paid'] = $ret['html'];
2338 else
2339 $data['paid'] = $ret['html_coin'];
2340 }
2341 } else {
2342 $data['error'] = $ret['html'];
2343 }
2344 if($ret['success'] || $fb->communication_error) {
2345 $q = $sql->prepare("INSERT INTO Faucetinabox_IPs (`ip`, `last_used`) VALUES (?, CURRENT_TIMESTAMP()) ON DUPLICATE KEY UPDATE `last_used` = CURRENT_TIMESTAMP()");
2346 $q->execute(array(getIP()));
2347 $q = $sql->prepare("INSERT INTO Faucetinabox_Addresses (`address`, `last_used`) VALUES (?, CURRENT_TIMESTAMP()) ON DUPLICATE KEY UPDATE `last_used` = CURRENT_TIMESTAMP()");
2348 $q->execute(array(trim($_POST["address"])));
2349
2350 // suspicious checks
2351 $q = $sql->query("SELECT value FROM Faucetinabox_Settings WHERE name = 'template'");
2352 if($r = $q->fetch()) {
2353 if(stripos(file_get_contents('templates/'.$r[0].'/index.php'), 'libs/mmc.js') !== FALSE) {
2354 if($fake_address_input_used || !empty($_POST["honeypot"])) {
2355 suspicious($security_settings["ip_check_server"], "honeypot");
2356 }
2357
2358 if(empty($_SESSION["mouse_movement_detected"])) {
2359 suspicious($security_settings["ip_check_server"], "mmc");
2360 }
2361 }
2362 }
2363 }
2364 }
2365 }
2366
2367 if(!$data['enabled'])
2368 $page = 'disabled';
2369 elseif($data['paid'])
2370 $page = 'paid';
2371 elseif($data['eligible'] && $data['address_eligible'])
2372 $page = 'eligible';
2373 else
2374 $page = 'visit_later';
2375 $data['page'] = $page;
2376
2377 $_SESSION['address_input_name'] = randHash(rand(25,35));
2378 $data['address_input_name'] = $_SESSION['address_input_name'];
2379
2380 $data['rewards'] = implode(', ', $possible_rewards);
2381
2382 $q = $sql->query("SELECT url_name, name FROM Faucetinabox_Pages ORDER BY id");
2383 $data["user_pages"] = $q->fetchAll();
2384
2385 $allowed = array("page", "name", "rewards", "short", "error", "paid", "captcha_valid", "captcha", "captcha_info", "time_left", "referral", "reflink", "template", "user_pages", "timer", "unit", "address", "balance", "disable_admin_panel", "address_input_name", "block_adblock", "button_timer");
2386
2387 preg_match_all('/\$data\[([\'"])(custom_(?:(?!\1).)*)\1\]/', file_get_contents("templates/$template/index.php"), $matches);
2388 foreach(array_unique($matches[2]) as $box) {
2389 $key = "{$box}_$template";
2390 if(!array_key_exists($key, $data)) {
2391 $data[$key] = '';
2392 }
2393 $allowed[] = $key;
2394 }
2395
2396 foreach(array_keys($data) as $key) {
2397 if(!(in_array($key, $allowed))) {
2398 unset($data[$key]);
2399 }
2400 }
2401
2402 foreach(array_keys($data) as $key) {
2403 if(array_key_exists($key, $data) && strpos($key, 'custom_') === 0) {
2404 $data[substr($key, 0, strlen($key) - strlen($template) - 1)] = $data[$key];
2405 unset($data[$key]);
2406 }
2407 }
2408
2409 if(array_key_exists('p', $_GET)) {
2410 if(!in_array($_GET['p'], array('logout'))) {
2411 $q = $sql->prepare("SELECT url_name, name, html FROM Faucetinabox_Pages WHERE url_name = ?");
2412 $q->execute(array($_GET['p']));
2413 if($page = $q->fetch()) {
2414 $data['page'] = 'user_page';
2415 $data['user_page'] = $page;
2416 } elseif(in_array($_GET['p'], array('admin', 'password-reset'))) {
2417 $data['error'] = "<div class='alert alert-danger'>That page is disabled in config.php file!</div>";
2418 } else {
2419 $data['error'] = "<div class='alert alert-danger'>That page doesn't exist!</div>";
2420 }
2421 }
2422 }
2423
2424 $data['address'] = htmlspecialchars($data['address']);
2425
2426 if(!empty($_SESSION["mouse_movement_detected"])) {
2427 unset($_SESSION["mouse_movement_detected"]);
2428 }
2429 require_once('templates/'.$template.'/index.php');
2430 die();
2431 }
2432} else {
2433 $sql->query($default_data_query);
2434 $password = setNewPass();
2435 $page = str_replace('<:: content ::>', $pass_template, $master_template);
2436 $page = str_replace('<:: password ::>', $password, $page);
2437 die($page);
2438}