backend.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. <?php
  2. set_include_path(get_include_path() . PATH_SEPARATOR .
  3. dirname(__FILE__) ."/include");
  4. /* remove ill effects of magic quotes */
  5. if (get_magic_quotes_gpc()) {
  6. function stripslashes_deep($value) {
  7. $value = is_array($value) ?
  8. array_map('stripslashes_deep', $value) : stripslashes($value);
  9. return $value;
  10. }
  11. $_POST = array_map('stripslashes_deep', $_POST);
  12. $_GET = array_map('stripslashes_deep', $_GET);
  13. $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
  14. $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
  15. }
  16. require_once "functions.php";
  17. require_once "sessions.php";
  18. require_once "db-prefs.php";
  19. require_once "sanity_check.php";
  20. require_once "version.php";
  21. require_once "config.php";
  22. require_once "prefs.php";
  23. require_once "users.php";
  24. $link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
  25. init_connection($link);
  26. $dt_add = get_script_dt_add();
  27. header('Content-Type: text/json; charset=utf-8');
  28. $op = $_REQUEST["op"];
  29. if (!$_SESSION["uid"] && $op != "fetch-profiles" && $op != "login") {
  30. print json_encode(array("error" => 6));
  31. return;
  32. } else if ($_SESSION["uid"]) {
  33. @$csrf_token = $_REQUEST["csrf_token"];
  34. $csrf_ignore = [ "login", "init", "titleforurl", "imgproxy",
  35. "vidproxy", "emoticons", "emoticons_list", "logout", "embed" ];
  36. if ($csrf_token != $_SESSION["csrf_token"] && !in_array($op, $csrf_ignore)) {
  37. print json_encode(array("error" => 6));
  38. return;
  39. }
  40. update_heartbeat($link);
  41. }
  42. if (!sanity_check($link)) { return; }
  43. switch ($op) {
  44. case "create-user":
  45. $login = strtolower(db_escape_string($_REQUEST["login"]));
  46. $rv = array();
  47. if ($_SESSION["access_level"] >= 10) {
  48. $result = db_query($link, "SELECT id FROM ttirc_users WHERE
  49. login = '$login'");
  50. if (db_num_rows($result) == 0) {
  51. $tmp_password = make_password();
  52. $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
  53. $pwd_hash = db_escape_string(encrypt_password($tmp_password, $salt, true));
  54. $rv[0] = T_sprintf("Created user %s with password <b>%s</b>.",
  55. $login, $tmp_password);
  56. db_query($link, "INSERT INTO ttirc_users
  57. (login, pwd_hash, email, nick, realname, salt)
  58. VALUES
  59. ('$login', '$pwd_hash', '[email protected]', '$login', '$login', '$salt')");
  60. } else {
  61. $rv[0] = T_sprintf("User %s already exists", $login);
  62. }
  63. $rv[1] = format_users($link);
  64. print json_encode($rv);
  65. }
  66. break;
  67. case "reset-password":
  68. $id = db_escape_string($_REQUEST["id"]);
  69. if ($_SESSION["access_level"] >= 10) {
  70. $tmp_password = make_password();
  71. $login = get_user_login($link, $id);
  72. $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
  73. $pwd_hash = db_escape_string(encrypt_password($tmp_password, $salt, true));
  74. db_query($link, "UPDATE ttirc_users SET pwd_hash = '$pwd_hash', salt = '$salt'
  75. WHERE id = '$id'");
  76. print json_encode(array("message" =>
  77. T_sprintf("Reset password of user %s to <b>%s</b>.", $login,
  78. $tmp_password)));
  79. }
  80. break;
  81. case "delete-user":
  82. $ids = db_escape_string($_REQUEST["ids"]);
  83. if ($_SESSION["access_level"] >= 10) {
  84. db_query($link, "DELETE FROM ttirc_users WHERE
  85. id in ($ids) AND id != " . $_SESSION["uid"]);
  86. print format_users($link);
  87. }
  88. break;
  89. case "users":
  90. if ($_SESSION["access_level"] >= 10) {
  91. show_users($link);
  92. }
  93. break;
  94. case "part-channel":
  95. $last_id = (int) db_escape_string($_REQUEST["last_id"]);
  96. $chan = db_escape_string($_REQUEST["chan"]);
  97. $connection_id = db_escape_string($_REQUEST["connection"]);
  98. if ($chan && valid_connection($link, $connection_id)) {
  99. handle_command($link, $connection_id, $chan, "/part");
  100. db_query($link, "DELETE FROM ttirc_channels WHERE channel = '$chan'
  101. AND connection_id = '$connection_id'");
  102. }
  103. $lines = get_new_lines($link, $last_id);
  104. $conn = get_conn_info($link);
  105. $chandata = get_chan_data($link);
  106. $params = get_misc_params($link);
  107. print json_encode(array($conn, $lines, $chandata, $params));
  108. break;
  109. case "query-user":
  110. $nick = db_escape_string(trim($_REQUEST["nick"]));
  111. $last_id = (int) db_escape_string($_REQUEST["last_id"]);
  112. $connection_id = db_escape_string($_REQUEST["connection"]);
  113. if ($nick && valid_connection($link, $connection_id)) {
  114. handle_command($link, $connection_id, $chan, "/query $nick");
  115. }
  116. $lines = get_new_lines($link, $last_id);
  117. $conn = get_conn_info($link);
  118. $chandata = get_chan_data($link);
  119. $params = get_misc_params($link);
  120. print json_encode(array($conn, $lines, $chandata, $params));
  121. break;
  122. case "send":
  123. $message = trim(shorten_urls($_REQUEST["message"]));
  124. $last_id = (int) db_escape_string($_REQUEST["last_id"]);
  125. $chan = db_escape_string($_REQUEST["chan"]);
  126. $connection_id = db_escape_string($_REQUEST["connection"]);
  127. $tab_type = db_escape_string($_REQUEST["tab_type"]);
  128. $send_only = $_REQUEST["send_only"] == "true";
  129. @$uniqid = db_escape_string($_REQUEST["uniqid"]);
  130. if ($message !== "" && valid_connection($link, $connection_id)) {
  131. if (strpos($message, "/") === 0) {
  132. handle_command($link, $connection_id, $chan, $message);
  133. } else {
  134. $popcon_matches = array();
  135. preg_match_all("/(:[^ :]+:)/", $message, $popcon_matches);
  136. $emoticons_map = get_emoticons_map();
  137. if ($emoticons_map && count($popcon_matches[0]) > 0) {
  138. foreach ($popcon_matches[0] as $emoticon) {
  139. if (isset($emoticons_map[$emoticon])) {
  140. $emoticon = db_escape_string($emoticon);
  141. $result = db_query($link, "SELECT id, times_used FROM ttirc_emoticons_popcon
  142. WHERE emoticon = '$emoticon' AND owner_uid = " . $_SESSION["uid"]);
  143. if (db_num_rows($result) == 0) {
  144. db_query($link, "INSERT INTO ttirc_emoticons_popcon (emoticon, times_used, owner_uid)
  145. VALUES ('$emoticon', 1, ".$_SESSION["uid"].")");
  146. } else {
  147. $ref_id = db_fetch_result($result, 0, "id");
  148. $times_used = db_fetch_result($result, 0, "times_used");
  149. # if ($times_used < 1024) {
  150. db_query($link, "UPDATE ttirc_emoticons_popcon SET times_used = times_used + 1
  151. WHERE id = $ref_id");
  152. # }
  153. }
  154. }
  155. }
  156. }
  157. if (is_instance($link, $connection_id)) {
  158. $lines = array_map("trim", explode("\n", $message));
  159. foreach ($lines as $line) {
  160. relay_message($link, $connection_id, $chan, $line);
  161. }
  162. } else {
  163. $lines = array_map("trim", explode("\n", $message));
  164. if ($tab_type == "P") {
  165. foreach ($lines as $line)
  166. if (mb_strlen($line) > 0)
  167. push_message($link, $connection_id, $chan, $line, false,
  168. MSGT_PRIVATE_PRIVMSG);
  169. } else {
  170. $l = 0;
  171. foreach ($lines as $line) {
  172. if (mb_strlen($line) > 0) {
  173. push_message($link, $connection_id, $chan, $line);
  174. ++$l;
  175. if ($l > 4) break;
  176. }
  177. }
  178. }
  179. }
  180. /* $lines = explode("\n", wordwrap($message, 200, "\n"));
  181. foreach ($lines as $line) {
  182. push_message($link, $connection_id, $chan, $line);
  183. } */
  184. }
  185. }
  186. if (!$send_only) {
  187. $lines = get_new_lines($link, $last_id);
  188. $conn = get_conn_info($link);
  189. $chandata = get_chan_data($link);
  190. //$params = get_misc_params($link);
  191. if ($uniqid) {
  192. if (serialize($conn) == $_SESSION["cache"][$uniqid]["conn"]) {
  193. $conn = array("duplicate" => true);
  194. } else {
  195. $_SESSION["cache"][$uniqid]["conn"] = serialize($conn);
  196. }
  197. if (serialize($chandata) == $_SESSION["cache"][$uniqid]["chandata"]) {
  198. $chandata = array("duplicate" => true);
  199. } else {
  200. $_SESSION["cache"][$uniqid]["chandata"] = serialize($chandata);
  201. }
  202. $_SESSION["cache"][$uniqid]["last"] = time();
  203. }
  204. $dup = array("duplicate" => true);
  205. print json_encode(array($conn, $lines, $chandata, $dup));
  206. }
  207. break;
  208. case "update":
  209. cleanup_session_cache();
  210. $last_id = (int) db_escape_string($_REQUEST["last_id"]);
  211. $init = db_escape_string($_REQUEST["init"]);
  212. @$uniqid = db_escape_string($_REQUEST["uniqid"]);
  213. if (!$init) {
  214. $sleep_start = time();
  215. while (time() - $sleep_start < UPDATE_DELAY_MAX &&
  216. !num_new_lines($link, $last_id)) {
  217. sleep(1);
  218. }
  219. }
  220. $lines = get_new_lines($link, $last_id);
  221. $conn = get_conn_info($link);
  222. $chandata = get_chan_data($link);
  223. $params = get_misc_params($link, $uniqid);
  224. $emoticons = array(array_merge(get_emoticons_map(false, true)), render_emoticons($link));
  225. if ($uniqid) {
  226. if (serialize($conn) == $_SESSION["cache"][$uniqid]["conn"]) {
  227. $conn = array("duplicate" => true);
  228. } else {
  229. $_SESSION["cache"][$uniqid]["conn"] = serialize($conn);
  230. }
  231. if (serialize($chandata) == $_SESSION["cache"][$uniqid]["chandata"]) {
  232. $chandata = array("duplicate" => true);
  233. } else {
  234. $_SESSION["cache"][$uniqid]["chandata"] = serialize($chandata);
  235. }
  236. if (serialize($params) == $_SESSION["cache"][$uniqid]["params"]) {
  237. $params = array("duplicate" => true);
  238. } else {
  239. $_SESSION["cache"][$uniqid]["params"] = serialize($params);
  240. }
  241. if (serialize($emoticons) == $_SESSION["cache"][$uniqid]["emoticons"]) {
  242. $emoticons = array("duplicate" => true);
  243. } else {
  244. $_SESSION["cache"][$uniqid]["emoticons"] = serialize($emoticons);
  245. }
  246. $_SESSION["cache"][$uniqid]["last"] = time();
  247. }
  248. print json_encode(array($conn, $lines, $chandata, $params, $emoticons));
  249. break;
  250. case "set-topic":
  251. $last_id = (int) db_escape_string($_REQUEST["last_id"]);
  252. $topic = strip_tags($_REQUEST["topic"]);
  253. $chan = db_escape_string($_REQUEST["chan"]);
  254. $connection_id = db_escape_string($_REQUEST["connection"]);
  255. if ($topic !== FALSE) {
  256. handle_command($link, $connection_id, $chan, "/topic $topic");
  257. }
  258. $lines = get_new_lines($link, $last_id);
  259. $conn = get_conn_info($link);
  260. $chandata = get_chan_data($link);
  261. $params = get_misc_params($link);
  262. print json_encode(array($conn, $lines, $chandata, $params));
  263. break;
  264. case "login":
  265. $login = db_escape_string($_REQUEST["user"]);
  266. $password = db_escape_string($_REQUEST["password"]);
  267. $result = db_query($link, "SELECT id FROM ttirc_users WHERE login = '$login'");
  268. if (db_num_rows($result) != 0) {
  269. $uid = db_fetch_result($result, 0, "id");
  270. } else {
  271. $uid = 0;
  272. }
  273. if (!$uid) {
  274. print json_encode(array("error" => 6));
  275. return;
  276. }
  277. if (authenticate_user($link, $login, $password)) {
  278. $_SESSION["csrf_token"] = uniqid_short();
  279. print json_encode(array("sid" => session_id(), "version" => VERSION,
  280. "uniqid" => uniqid(), "csrf_token" => $_SESSION["csrf_token"]));
  281. } else {
  282. print json_encode(array("error" => 6));
  283. }
  284. break;
  285. case "init":
  286. $dbh = Db::get();
  287. $sth = $dbh->prepare("SELECT MAX(ttirc_messages.id) AS max_id
  288. FROM ttirc_messages, ttirc_connections
  289. WHERE connection_id = ttirc_connections.id AND owner_uid = ?");
  290. $sth->execute([$_SESSION["uid"]]);
  291. $rv = array();
  292. if ($row = $sth->fetch()) {
  293. $rv["max_id"] = $row['max_id'];
  294. } else {
  295. $rv["max_id"] = 0;
  296. }
  297. $rv["status"] = 1;
  298. $rv["theme"] = get_pref($link, "USER_THEME");
  299. $rv["update_delay_max"] = UPDATE_DELAY_MAX;
  300. $rv["uniqid"] = uniqid();
  301. $rv["emoticons"] = array_merge(get_emoticons_map(false, true));
  302. $rv["csrf_token"] = $_SESSION["csrf_token"];
  303. print json_encode($rv);
  304. break;
  305. case "prefs":
  306. main_prefs($link);
  307. break;
  308. case "prefs-conn-save":
  309. $title = db_escape_string($_REQUEST["title"]);
  310. $autojoin = db_escape_string($_REQUEST["autojoin"]);
  311. $connect_cmd = db_escape_string($_REQUEST["connect_cmd"]);
  312. $encoding = db_escape_string($_REQUEST["encoding"]);
  313. $nick = db_escape_string($_REQUEST["nick"]);
  314. $auto_connect = bool_to_sql_bool(db_escape_string($_REQUEST["auto_connect"]));
  315. $permanent = bool_to_sql_bool(db_escape_string($_REQUEST["permanent"]));
  316. $connection_id = db_escape_string($_REQUEST["connection_id"]);
  317. $visible = bool_to_sql_bool(db_escape_string($_REQUEST["visible"]));
  318. $server_password = db_escape_string($_REQUEST["server_password"]);
  319. $use_ssl = bool_to_sql_bool(db_escape_string($_REQUEST["use_ssl"]));
  320. if (!$title) $title = __("[Untitled]");
  321. if (valid_connection($link, $connection_id)) {
  322. db_query($link, "UPDATE ttirc_connections SET title = '$title',
  323. autojoin = '$autojoin',
  324. connect_cmd = '$connect_cmd',
  325. auto_connect = $auto_connect,
  326. server_password = '$server_password',
  327. visible = $visible,
  328. use_ssl = $use_ssl,
  329. nick = '$nick',
  330. encoding = '$encoding',
  331. permanent = $permanent
  332. WHERE id = '$connection_id'");
  333. //print json_encode(array("error" => "Function not implemented."));
  334. }
  335. print json_encode(["status" => "OK"]);
  336. break;
  337. case "prefs-save":
  338. //print json_encode(array("error" => "Function not implemented."));
  339. $realname = db_escape_string($_REQUEST["realname"]);
  340. $quit_message = db_escape_string($_REQUEST["quit_message"]);
  341. $new_password = db_escape_string($_REQUEST["new_password"]);
  342. $confirm_password = db_escape_string($_REQUEST["confirm_password"]);
  343. $nick = db_escape_string($_REQUEST["nick"]);
  344. $email = db_escape_string($_REQUEST["email"]);
  345. $theme = db_escape_string($_REQUEST["theme"]);
  346. $highlight_on = db_escape_string($_REQUEST["highlight_on"]);
  347. $hide_join_part = bool_to_sql_bool(db_escape_string($_REQUEST["hide_join_part"]));
  348. $disable_image_preview = bool_to_sql_bool(db_escape_string($_REQUEST["disable_image_preview"]));
  349. $theme_changed = false;
  350. $_SESSION["prefs_cache"] = false;
  351. if (get_user_theme($link) != $theme) {
  352. set_pref($link, "USER_THEME", $theme);
  353. $theme_changed = true;
  354. }
  355. set_pref($link, "HIGHLIGHT_ON", $highlight_on);
  356. set_pref($link, "DISABLE_IMAGE_PREVIEW", $disable_image_preview);
  357. db_query($link, "UPDATE ttirc_users SET realname = '$realname',
  358. quit_message = '$quit_message',
  359. email = '$email',
  360. hide_join_part = $hide_join_part,
  361. nick = '$nick' WHERE id = " . $_SESSION["uid"]);
  362. if ($new_password != $confirm_password) {
  363. print json_encode(array("error" => "Passwords do not match."));
  364. return;
  365. }
  366. if ($confirm_password == $new_password && $new_password) {
  367. $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
  368. $pwd_hash = encrypt_password($new_password, $salt, true);
  369. db_query($link, "UPDATE ttirc_users SET pwd_hash = '$pwd_hash', salt = '$salt'
  370. WHERE id = ". $_SESSION["uid"]);
  371. }
  372. if ($theme_changed) {
  373. print json_encode(array("message" => "THEME_CHANGED"));
  374. return;
  375. }
  376. break;
  377. case "prefs-edit-con":
  378. $connection_id = (int) db_escape_string($_REQUEST["id"]);
  379. connection_editor($link, $connection_id);
  380. break;
  381. case "prefs-customize-css":
  382. css_editor($link);
  383. break;
  384. case "prefs-save-css":
  385. $user_css = db_escape_string($_REQUEST["user_css"]);
  386. set_pref($link, "USER_STYLESHEET", $user_css);
  387. print json_encode(["status" => "OK"]);
  388. //print json_encode(array("error" => "Function not implemented."));
  389. break;
  390. case "create-server":
  391. $connection_id = (int) db_escape_string($_REQUEST["connection_id"]);
  392. list($server, $port) = explode(":", db_escape_string($_REQUEST["data"]));
  393. if (valid_connection($link, $connection_id)) {
  394. if ($server && $port) {
  395. db_query($link, "INSERT INTO ttirc_servers (server, port, connection_id)
  396. VALUES ('$server', '$port', '$connection_id')");
  397. print_servers($link, $connection_id);
  398. } else {
  399. $error = T_sprintf("Couldn't add server (%s:%d): Invalid syntax.",
  400. $server, $port);
  401. print json_encode(array("error" => $error));
  402. }
  403. }
  404. break;
  405. case "delete-server":
  406. $ids = db_escape_string($_REQUEST["ids"]);
  407. $connection_id = (int) db_escape_string($_REQUEST["connection_id"]);
  408. if (valid_connection($link, $connection_id)) {
  409. db_query($link, "DELETE FROM ttirc_servers WHERE
  410. id in ($ids) AND connection_id = '$connection_id'");
  411. print_servers($link, $connection_id);
  412. }
  413. break;
  414. case "delete-connection":
  415. $ids = db_escape_string($_REQUEST["ids"]);
  416. db_query($link, "DELETE FROM ttirc_connections WHERE
  417. id IN ($ids) AND status = 0 AND owner_uid = ".$_SESSION["uid"]);
  418. print_connections($link);
  419. break;
  420. case "create-connection":
  421. $title = db_escape_string(trim($_REQUEST["title"]));
  422. if ($title) {
  423. db_query($link, "INSERT INTO ttirc_connections (enabled, title, owner_uid)
  424. VALUES ('false', '$title', '".$_SESSION["uid"]."')");
  425. }
  426. print_connections($link);
  427. break;
  428. case "fetch-profiles":
  429. $login = db_escape_string($_REQUEST["login"]);
  430. $password = db_escape_string($_REQUEST["password"]);
  431. if (authenticate_user($link, $login, $password)) {
  432. $result = db_query($link, "SELECT * FROM ttirc_settings_profiles
  433. WHERE owner_uid = " . $_SESSION["uid"] . " ORDER BY title");
  434. print "<select style='width: 100%' name='profile'>";
  435. print "<option value='0'>" . __("Default profile") . "</option>";
  436. while ($line = db_fetch_assoc($result)) {
  437. $id = $line["id"];
  438. $title = $line["title"];
  439. print "<option value='$id'>$title</option>";
  440. }
  441. print "</select>";
  442. $_SESSION = array();
  443. }
  444. break;
  445. case "toggle-connection":
  446. $connection_id = (int) db_escape_string($_REQUEST["connection_id"]);
  447. $status = bool_to_sql_bool(db_escape_string($_REQUEST["set_enabled"]));
  448. db_query($link, "UPDATE ttirc_connections SET enabled = $status
  449. WHERE id = '$connection_id' AND owner_uid = " . $_SESSION["uid"]);
  450. print json_encode(array("status" => $status));
  451. break;
  452. case "prefs-edit-notify":
  453. notification_editor($link);
  454. break;
  455. case "prefs-save-notify":
  456. $notify_events = json_encode($_REQUEST["notify_event"]);
  457. set_pref($link, "NOTIFY_ON", $notify_events);
  458. print json_encode(["status" => "OK"]);
  459. break;
  460. case "preview":
  461. $url = htmlspecialchars($_REQUEST["url"]);
  462. header("Location: $url");
  463. break;
  464. case "emoticons":
  465. print json_encode(get_emoticons_map());
  466. break;
  467. case "emoticons_list":
  468. header('Content-Type: text/html; charset=utf-8');
  469. render_emoticons_full();
  470. break;
  471. case "embed":
  472. $url = htmlspecialchars($_REQUEST["url"]);
  473. header("Content-type: text/html");
  474. print "<html><head>
  475. <title>Tiny Tiny IRC: $url</title>
  476. <style type='text/css'>
  477. body { background : #333;
  478. margin : 0px; padding : 0px;
  479. text-align : center;
  480. height : 100%; width : 100%; }
  481. video, img.fit { max-width : 100%; max-height : 100%;
  482. width : auto; height : auto;
  483. position : relative; top : 50%; transform: translateY(-50%); }
  484. img {
  485. cursor : pointer;
  486. }
  487. </style></head><body>";
  488. print javascript_tag("lib/bootstrap/js/jquery.js");
  489. if (preg_match("/\.(mp4|webm|gifv)/", $url, $matches)) {
  490. $type = $matches[1];
  491. $embed_url = $url;
  492. if ($type == "gifv") {
  493. $type = "mp4";
  494. $embed_url = str_replace(".gifv", ".mp4", $embed_url);
  495. }
  496. header("Content-type: text/html");
  497. print "<video class=\"\" autoplay=\"true\" controls=\"true\" loop=\"true\">";
  498. print "<source src=\"$embed_url\" type=\"video/$type\">";
  499. print "</video>";
  500. print "<script type='text/javascript'>
  501. $('video').height($(document).height() * 0.95);
  502. </script>";
  503. } else {
  504. print "<img class=\"fit\" src=\"$url\">";
  505. print "<script type='text/javascript'>
  506. $('img').click(function(e) {
  507. $(this).toggleClass('fit');
  508. });
  509. </script>";
  510. }
  511. print "</body></html>";
  512. break;
  513. case "vidproxy";
  514. $url = $_REQUEST["url"];
  515. if (preg_match("/\.(mp4|webm|gifv)/", $url, $matches)) {
  516. $type = $matches[1];
  517. $embed_url = $url;
  518. if ($type == "gifv") {
  519. $type = "mp4";
  520. $embed_url = str_replace(".gifv", ".mp4", $embed_url);
  521. }
  522. header("Content-type: text/html");
  523. $embed_url = htmlspecialchars("backend.php?op=imgproxy&url=" . urlencode($embed_url));
  524. print "<video class=\"\" autoplay=\"true\" controls=\"true\" loop=\"true\">";
  525. print "<source src=\"$embed_url\" type=\"video/$type\">";
  526. print "</video>";
  527. } else {
  528. header("Location: " . htmlspecialchars($url));
  529. }
  530. break;
  531. case "chanmute":
  532. $connection_id = (int) $_REQUEST["connection_id"];
  533. $channel = db_escape_string($_REQUEST["channel"]);
  534. if ($channel != "---") {
  535. $result = db_query($link, "SELECT id FROM ttirc_connections WHERE
  536. id = '$connection_id' AND owner_uid = " . $_SESSION["uid"]);
  537. if (db_num_rows($result) > 0) {
  538. $result = db_query($link, "UPDATE ttirc_channels SET muted = NOT muted
  539. WHERE connection_id = '$connection_id' AND channel = '$channel' RETURNING muted");
  540. if (db_num_rows($result) > 0) {
  541. $muted = db_fetch_result($result, 0, "muted");
  542. print json_encode(["connection_id" => $connection_id,
  543. "channel" => $channel, "muted" => sql_bool_to_bool($muted) ]);
  544. }
  545. }
  546. } else {
  547. $result = db_query($link, "UPDATE ttirc_connections SET muted = NOT muted
  548. WHERE id = '$connection_id' AND owner_uid = " . $_SESSION["uid"] . " RETURNING muted");
  549. if (db_num_rows($result) > 0) {
  550. $muted = db_fetch_result($result, 0, "muted");
  551. print json_encode(["connection_id" => $connection_id,
  552. "channel" => "---", "muted" => sql_bool_to_bool($muted) ]);
  553. }
  554. }
  555. break;
  556. case "uploadandpost":
  557. $file = $_FILES['file'];
  558. $reason = "";
  559. if (!is_writable("cache/uploads")) {
  560. $reason = __("Cache not writable");
  561. } else if (!$file) {
  562. $reason = __("No file uploaded.");
  563. } else if ($file['size'] > 5000000) {
  564. $reason = __("File is too large.");
  565. } else {
  566. $new_file_name = 'cache/uploads/' . time() . '-' . basename($file['name']);
  567. $result = move_uploaded_file($file['tmp_name'], $new_file_name);
  568. if ($result) {
  569. chmod($new_file_name, 0644);
  570. $url = get_self_url_prefix() . "/$new_file_name";
  571. if (function_exists("shorten_url")) $url = shorten_url($url);
  572. print json_encode(['upload_url' => $url]);
  573. $files = glob("cache/uploads/*");
  574. foreach ($files as $file) {
  575. if (time() - filemtime($file) > 86400*7) {
  576. unlink($file);
  577. }
  578. }
  579. return;
  580. } else {
  581. $reason = __("Error moving file.");
  582. }
  583. }
  584. print json_encode(["status" => "UPLOAD_FAILED", "reason" => $reason]);
  585. break;
  586. case "titleforurl":
  587. if (defined('FETCH_URL_TITLES') && FETCH_URL_TITLES && class_exists("Memcached")) {
  588. $srv = explode(":", MEMCACHE_SERVER, 2);
  589. $cache = new Memcached();
  590. $cache->addServer($srv[0], $srv[1]);
  591. ini_set('user_agent', 'Mozilla/5.0 (compatible)');
  592. $base_url = $_SERVER["REQUEST_SCHEME"] . "://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
  593. $url = rewrite_relative_url($base_url, $_REQUEST["url"]);
  594. $key = 'ttirc.urlcache:' . sha1($url);
  595. $nocache = (bool) $_REQUEST["nocache"];
  596. if ($nocache || !$rv = $cache->get($key)) {
  597. $rv = [ 'url' => $url];
  598. $ctx = stream_context_create(array('http'=>array('timeout' => 3)));
  599. $data = @file_get_contents($url, false, $ctx);
  600. if ($data) {
  601. $data = mb_substr($data, 0, 32768);
  602. $doc = new DOMDocument('UTF-8');
  603. $preamble = '<?xml encoding="utf-8" ?>\n';
  604. if (@$doc->loadHTML($preamble . $data)) {
  605. $node = $doc->getElementsByTagName('title')->item(0);
  606. if ($node) {
  607. $rv['title'] = preg_replace("/[\r\n\t]/", "", trim($node->nodeValue));
  608. $cache->set($key, $rv, 86400 * 12);
  609. }
  610. }
  611. }
  612. }
  613. print json_encode($rv);
  614. }
  615. break;
  616. case "imgproxy";
  617. $base_url = $_SERVER["REQUEST_SCHEME"] . "://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
  618. $url = rewrite_relative_url($base_url, $_REQUEST["url"]);
  619. if (function_exists("getimagesize")) {
  620. $is = @getimagesize($url);
  621. header("Content-type: " . $is["mime"]);
  622. }
  623. readfile($url);
  624. break;
  625. case "logout":
  626. logout_user();
  627. header("Location: index.php");
  628. break;
  629. }
  630. ?>