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