Friendly, easy, lightweight, self-hostable CAPTCHA service. https://captcheck.netsyms.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

api.php 4.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. require __DIR__ . '/required.php';
  3. header("Content-Type: application/json");
  4. // Oldest session allowed
  5. $session_min_date = date("Y-m-d H:i:s", strtotime("-" . SESSION_EXPIRE_MINUTES . " minutes"));
  6. // Delete old sessions
  7. $old_sessions = $database->select("sessions", "sid", ["timestamp[<]" => $session_min_date]);
  8. $database->delete("scrambled_answers", ["sid" => $old_sessions]);
  9. $database->delete("sessions", ["sid" => $old_sessions]);
  10. switch ($VARS['action']) {
  11. case "ping":
  12. $out = ["status" => "OK", "pong" => true];
  13. exit(json_encode($out));
  14. case "new":
  15. // generate unique session ID that has an essentially zero chance of being a duplicate.
  16. // Contains a hash of a secure random number, a hash of the user's IP, and 23 uniqid() characters.
  17. $skey = uniqid(substr(hash("md5", mt_rand()), 3, 5) . hash("md5", getUserIP()), true);
  18. $answers = $database->select('answers', ['aid', 'aname']);
  19. shuffle($answers);
  20. $answers = array_slice($answers, 0, 5);
  21. //var_dump($answers);
  22. $correct_answer = $answers[mt_rand(0, count($answers) - 1)];
  23. $scrambled = ["real" => [], "fake" => []];
  24. foreach ($answers as $a) {
  25. $scrambled["real"][] = $a['aid'];
  26. $scrambled["fake"][] = substr(hash("md5", mt_rand()), 0, 20);
  27. }
  28. $database->insert("sessions", ["skey" => $skey, "aid" => $correct_answer['aid'], "expired" => 0, "#timestamp" => "NOW()"]);
  29. $sid = $database->id();
  30. $scrambled_insert = [];
  31. for ($i = 0; $i < count($scrambled['real']); $i++) {
  32. $scrambled_insert[] = ["sid" => $sid, "aid" => $scrambled['real'][$i], "acode" => $scrambled['fake'][$i]];
  33. }
  34. $database->insert("scrambled_answers", $scrambled_insert);
  35. $resp = [
  36. "session" => $skey,
  37. "question" => $correct_answer['aname'],
  38. "answers" => $scrambled["fake"]
  39. ];
  40. exit(json_encode($resp));
  41. case "img":
  42. if (!$database->has('sessions', ['skey' => $VARS['s']])) {
  43. sendError("Missing or invalid session ID.", "client");
  44. }
  45. $sid = $database->get('sessions', 'sid', ['skey' => $VARS['s']]);
  46. if (!$database->has("scrambled_answers", ["AND" => ["sid" => $sid, "acode" => $VARS['c']]])) {
  47. sendError("Missing or invalid image code.", "client");
  48. }
  49. $imgid = $database->get("scrambled_answers", ["[>]answers" => ["aid" => "aid"]], 'aimg', ["AND" => ["sid" => $sid, "acode" => $VARS['c']]]);
  50. /* Load image, add some black/white noise, and send */
  51. header('Content-Type: image/png');
  52. $imgpath = __DIR__ . "/images/" . $imgid . ".png";
  53. if (DEBUG) {
  54. file_put_contents("debug", $imgpath . "\n", FILE_APPEND);
  55. }
  56. $img = imagecreatefrompng($imgpath);
  57. imageAlphaBlending($img, true);
  58. imageSaveAlpha($img, true);
  59. $black = imagecolorallocate($img, 0, 0, 0);
  60. $white = imagecolorallocate($img, 255, 255, 255);
  61. for ($i = 0; $i < 512; $i++) {
  62. imagesetpixel($img, mt_rand(0, 63), mt_rand(0, 63), $black);
  63. }
  64. for ($i = 0; $i < 256; $i++) {
  65. imagesetpixel($img, mt_rand(0, 63), mt_rand(0, 63), $white);
  66. }
  67. imagepng($img);
  68. exit();
  69. case "verify":
  70. if (!$database->has('sessions', ['skey' => $VARS['session_id']])) {
  71. echo json_encode(["session" => $VARS['session_id'], "result" => false, "msg" => "Session invalid."]);
  72. exit();
  73. }
  74. $sid = $database->get('sessions', 'sid', ['skey' => $VARS['session_id']]);
  75. $expired = ($database->get('sessions', 'expired', ['skey' => $VARS['session_id']]) == 1 ? true : false);
  76. if ($expired) {
  77. echo json_encode(["session" => $VARS['session_id'], "result" => false, "msg" => "Session key already used."]);
  78. exit();
  79. }
  80. if (!$database->has("scrambled_answers", ["AND" => ["sid" => $sid, "acode" => $VARS['answer_id']]])) {
  81. echo json_encode(["session" => $VARS['session_id'], "result" => false, "msg" => "Answer invalid."]);
  82. exit();
  83. }
  84. $aid = $database->get('scrambled_answers', 'aid', ["AND" => ["sid" => $sid, "acode" => $VARS['answer_id']]]);
  85. if ($database->has('sessions', ["AND" => ["sid" => $sid, "aid" => $aid]])) {
  86. echo json_encode(["session" => $VARS['session_id'], "result" => true]);
  87. } else {
  88. echo json_encode(["session" => $VARS['session_id'], "result" => false, "msg" => "Answer incorrect."]);
  89. }
  90. $database->update("sessions", ['expired' => 1], ["sid" => $sid]);
  91. exit();
  92. default:
  93. sendError("Bad Request", "client");
  94. }