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