Guest User

faucet

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