index.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php
  2. set_time_limit(0);
  3. header('X-Accel-Buffering: no');
  4. $FF_TOKEN = $_GET['ff-token'] ?? '';
  5. $VERIFIED = $FF_TOKEN === getenv('FF_TOKEN');
  6. ?>
  7. <!DOCTYPE html>
  8. <html lang="zh-cmn-Hans">
  9. <head>
  10. <meta charset="UTF-8">
  11. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no"/>
  12. <meta name="renderer" content="webkit"/>
  13. <meta name="force-rendering" content="webkit"/>
  14. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
  15. <title>Freenom 续期控制台 | 你只需部署,剩下的事情交给我们</title>
  16. <link rel="stylesheet" href="css/mdui.min.css"/>
  17. <style>
  18. .loading-icon {
  19. width: 17px;
  20. height: 17px;
  21. margin-right: 10px;
  22. margin-top: -6px;
  23. font-size: 18px;
  24. }
  25. .success-icon {
  26. margin-top: -6px;
  27. margin-right: 10px;
  28. }
  29. #copy-btn {
  30. border-radius: 16px;
  31. }
  32. #output-box {
  33. word-wrap: break-word;
  34. font-size: 14px;
  35. }
  36. .a-tag {
  37. color: #f44336;
  38. text-decoration: none;
  39. font-weight: bold;
  40. }
  41. @-webkit-keyframes shake {
  42. 0% {
  43. opacity: 1;
  44. }
  45. 50% {
  46. opacity: 0;
  47. }
  48. 100% {
  49. opacity: 1;
  50. }
  51. }
  52. @keyframes shake {
  53. 0% {
  54. opacity: 1;
  55. }
  56. 50% {
  57. opacity: 0;
  58. }
  59. 100% {
  60. opacity: 1;
  61. }
  62. }
  63. .shake {
  64. -webkit-animation: shake 2s infinite;
  65. animation: shake 2s infinite;
  66. }
  67. </style>
  68. </head>
  69. <body>
  70. <div class="mdui-container">
  71. <div class="mdui-ripple mdui-ripple-yellow"
  72. mdui-tooltip="{content: '前往项目 GitHub 仓库', position: 'auto', delay: 500}">
  73. <a href="https://github.com/luolongfei/freenom" target="_blank">
  74. <img class="mdui-img-rounded mdui-center mdui-valign mdui-img-fluid" src="images/logo_bear.png" alt="logo"/>
  75. </a>
  76. </div>
  77. <ul class="mdui-list mdui-m-t-4">
  78. <li class="mdui-list-item mdui-ripple mdui-shadow-1">
  79. <div class="mdui-list-item-avatar">
  80. <img src="https://q2.qlogo.cn/headimg_dl?dst_uin=593198779&spec=100" alt="作者头像"/>
  81. </div>
  82. <div class="mdui-list-item-content">
  83. Freenom 续期控制台
  84. </div>
  85. </li>
  86. </ul>
  87. <?php if ($VERIFIED) { ?>
  88. <div class="mdui-panel" mdui-panel>
  89. <div class="mdui-panel-item mdui-panel-item-open">
  90. <div class="mdui-panel-item-header">
  91. 如何使用
  92. </div>
  93. <div class="mdui-panel-item-body">
  94. <p>1、点击 <strong><a href="https://uptimerobot.com/"
  95. target="_blank" class="a-tag">https://uptimerobot.com</a></strong>,前往 <strong>uptimerobot</strong>
  96. 注册一个账户,并登录</p>
  97. <p>2、点击右边的按钮,以复制此地址 <strong><span
  98. class="mdui-text-color-red" id="app-url"></span></strong>
  99. <button class="mdui-btn mdui-btn-raised mdui-btn-dense mdui-ripple mdui-color-pink-accent"
  100. id="copy-btn" data-clipboard-target="#app-url">
  101. 复制地址
  102. </button>
  103. </p>
  104. <p>3、回到 <a href="https://uptimerobot.com/dashboard#mainDashboard" target="_blank"
  105. class="a-tag">https://uptimerobot.com/dashboard#mainDashboard</a>,点击
  106. <strong class="mdui-text-color-green">Add New Monitor</strong> 添加新的监控任务,如何填写各项配置请点击下方
  107. <strong class="mdui-text-color-green">查看 Uptimerobot 配置图片</strong>,注意将 <strong>URL</strong>
  108. 地址替换成你上一步复制的地址
  109. </p>
  110. <div class="mdui-panel" mdui-panel>
  111. <div class="mdui-panel-item">
  112. <div class="mdui-panel-item-header">查看 Uptimerobot 配置图片</div>
  113. <div class="mdui-panel-item-body">
  114. <p><a href="https://s1.ax1x.com/2022/08/19/vsp9zQ.png" target="_blank"><img
  115. src="https://s1.ax1x.com/2022/08/19/vsp9zQ.png"
  116. class="mdui-img-fluid"
  117. alt="点我查看 uptimerobot 配置图片"/></a>
  118. </p>
  119. </div>
  120. </div>
  121. </div>
  122. </div>
  123. </div>
  124. <?php } else { ?>
  125. <div class="mdui-panel" mdui-panel>
  126. <div class="mdui-panel-item mdui-panel-item-open">
  127. <div class="mdui-panel-item-header">
  128. 请先验证身份
  129. </div>
  130. <div class="mdui-panel-item-body">
  131. <div class="mdui-textfield mdui-textfield-floating-label">
  132. <i class="mdui-icon material-icons">lock</i>
  133. <label class="mdui-textfield-label" for="pwd">请输入你在 Heroku 配置的 FF_TOKEN
  134. 的值,即令牌</label>
  135. <input class="mdui-textfield-input" type="text" id="pwd"/>
  136. <div class="mdui-textfield-helper">
  137. 点击上行文字即可输入内容,输入完成后,请点击下方送信按钮以验证身份
  138. </div>
  139. </div>
  140. <button class="mdui-btn mdui-btn-block mdui-color-red mdui-ripple" id="submit-btn">
  141. 送信
  142. </button>
  143. </div>
  144. </div>
  145. </div>
  146. <script>
  147. let submitBtn = document.getElementById('submit-btn');
  148. submitBtn.onclick = function () {
  149. let ffToken = document.getElementById('pwd').value;
  150. ffToken = ffToken.replace(/\s/g, '');
  151. if (ffToken.length < 1) {
  152. mdui.snackbar({message: '请输入令牌'});
  153. return;
  154. }
  155. submitBtn.disabled = true;
  156. submitBtn.innerText = '送信中...';
  157. window.location.href = '?ff-token=' + ffToken;
  158. }
  159. </script>
  160. <?php } ?>
  161. <div class="mdui-panel-item mdui-panel-item-open" id="shell-box">
  162. <div class="mdui-panel-item-header" id="shell-title">
  163. <div id="running-box">
  164. <i class="mdui-icon material-icons loading-icon mdui-text-color-red shake">fiber_manual_record</i>
  165. 正在执行
  166. </div>
  167. <div id="success-box" style="display: none;">
  168. <i class="mdui-icon material-icons mdui-text-color-green-500 success-icon">check_circle</i>完成
  169. </div>
  170. </div>
  171. <div class="mdui-panel-item-body mdui-color-black" id="output-box">
  172. <?php
  173. if ($VERIFIED) {
  174. echo '<p>Freenom 自动续期工具</p>';
  175. echo '<p>开始执行</p><br>';
  176. $cmd = 'php /app/run';
  177. while (@ob_end_flush()) ;
  178. $proc = popen($cmd, 'r');
  179. while (!feof($proc)) {
  180. echo '<p>' . fread($proc, 4096) . '</p>';
  181. @flush();
  182. }
  183. echo '<p>执行完了</p>';
  184. echo '<p>Made with <i class="mdui-icon material-icons mdui-text-color-pink-a200 shake">favorite</i> by <a class="mdui-text-color-white-text" href="https:\/\/github.com/luolongfei" target="_blank">luolongfei</a></p>';
  185. echo '<script type="text/javascript">',
  186. "document.getElementById('running-box').style.display = 'none';
  187. document.getElementById('success-box').style.display = 'block';",
  188. '</script>';
  189. } else {
  190. echo '<p>你没有权限触发执行</p>';
  191. echo '<script type="text/javascript">',
  192. 'document.getElementById("shell-title").innerHTML = "啊,出错啦";',
  193. '</script>';
  194. }
  195. ?>
  196. </div>
  197. </div>
  198. </div>
  199. <div class="mdui-dialog" id="donation-dialog">
  200. <div class="mdui-dialog-content">
  201. <ul class="mdui-list mdui-list-dense">
  202. <li class="mdui-list-item mdui-ripple">
  203. <div class="mdui-list-item-avatar">
  204. <img src="https://q2.qlogo.cn/headimg_dl?dst_uin=593198779&spec=100" alt="作者头像"/>
  205. </div>
  206. <div class="mdui-list-item-content">
  207. <div class="mdui-list-item-title">Freenom 续期工具</div>
  208. <div class="mdui-list-item-text mdui-list-item-two-line">
  209. <span class="mdui-text-color-theme-text">如果你觉得本项目对你有帮助,请考虑赞助本项目。</span>
  210. </div>
  211. </div>
  212. </li>
  213. </ul>
  214. <div class="mdui-card">
  215. <div class="mdui-card-media">
  216. <img class="mdui-img-rounded" src="https://s2.ax1x.com/2020/01/31/1394at.png" alt="赞助二维码"/>
  217. </div>
  218. <div class="mdui-card-content">
  219. <div id="smart-button-container">
  220. <div style="text-align: center;">
  221. <div id="paypal-button-container"></div>
  222. </div>
  223. </div>
  224. <script type='text/javascript' src='https://storage.ko-fi.com/cdn/widget/Widget_2.js'></script>
  225. <script type='text/javascript'>kofiwidget2.init('Support Me on Ko-fi', '#F05D59', 'X7X8CA7S1');
  226. kofiwidget2.draw();</script>
  227. </div>
  228. </div>
  229. </div>
  230. <div class="mdui-dialog-actions">
  231. <button class="mdui-btn mdui-ripple" mdui-dialog-close>不了</button>
  232. <button class="mdui-btn mdui-ripple" mdui-dialog-close
  233. onclick="mdui.snackbar({message: '赞助在哪里,我没收到呢'});">已赞助
  234. </button>
  235. </div>
  236. </div>
  237. </div>
  238. <div class="mdui-container">
  239. <p>
  240. <a href="https://github.com/luolongfei/freenom" target="_blank"
  241. class="mdui-btn mdui-btn-raised mdui-ripple"><i class="mdui-icon material-icons">link</i>
  242. 访问仓库</a>
  243. <a href="https://github.com/luolongfei/freenom/wiki/Donation-List"
  244. class="mdui-btn mdui-btn-raised mdui-ripple mdui-color-theme-accent"
  245. target="_blank"><i class="mdui-icon material-icons">format_list_bulleted</i>
  246. 赞助名单
  247. </a>
  248. <button class="mdui-btn mdui-btn-raised mdui-ripple mdui-color-theme-accent"
  249. mdui-dialog="{target: '#donation-dialog'}"><i class="mdui-icon material-icons">exposure_plus_1</i>
  250. 赞助作者
  251. </button>
  252. </p>
  253. </div>
  254. <script src="js/mdui.min.js"></script>
  255. <script src="js/clipboard.min.js"></script>
  256. <script src="https://www.paypal.com/sdk/js?client-id=sb&enable-funding=venmo&currency=USD"
  257. data-sdk-integration-source="button-factory"></script>
  258. <?php
  259. if ($FF_TOKEN !== '' && !$VERIFIED) { // 验证失败
  260. echo '<script type="text/javascript">',
  261. "mdui.snackbar({message: '你输入的令牌有误,请重试'});",
  262. '</script>';
  263. }
  264. if ($VERIFIED) { // 验证成功
  265. ?>
  266. <script type="text/javascript">
  267. document.getElementById('app-url').innerHTML = `https://${document.domain}/?ff-token=<?php echo $FF_TOKEN; ?>`;
  268. let clipboard = new ClipboardJS('#copy-btn');
  269. clipboard.on('success', function (e) {
  270. console.info('Action:', e.action);
  271. console.info('Text:', e.text);
  272. console.info('Trigger:', e.trigger);
  273. mdui.snackbar({message: '复制成功'});
  274. e.clearSelection();
  275. });
  276. clipboard.on('error', function (e) {
  277. console.error('Action:', e.action);
  278. console.error('Trigger:', e.trigger);
  279. alert('复制失败,请手动复制');
  280. });
  281. setTimeout(function () {
  282. document.getElementById('shell-box').scrollIntoView({behavior: 'smooth', block: 'start', inline: 'start'});
  283. }, 1500);
  284. </script>
  285. <?php
  286. }
  287. ?>
  288. <script>
  289. function initPayPalButton() {
  290. paypal.Buttons({
  291. style: {
  292. shape: 'rect',
  293. color: 'gold',
  294. layout: 'horizontal',
  295. label: 'paypal',
  296. },
  297. createOrder: function (data, actions) {
  298. return actions.order.create({
  299. purchase_units: [{
  300. "description": "赞助 freenom 自动续期脚本的作者,以促进项目持续发展。",
  301. "amount": {"currency_code": "USD", "value": 5}
  302. }]
  303. });
  304. },
  305. onApprove: function (data, actions) {
  306. return actions.order.capture().then(function (orderData) {
  307. const element = document.getElementById('paypal-button-container');
  308. element.innerHTML = '';
  309. element.innerHTML = '<h3>Thank you for your payment!</h3>';
  310. });
  311. },
  312. onError: function (err) {
  313. console.log(err);
  314. }
  315. }).render('#paypal-button-container');
  316. }
  317. initPayPalButton();
  318. </script>
  319. </body>
  320. </html>