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.3KB

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