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