From 6c7dd233284ba78465d06a4c0862f6d3d3d3a7ad Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Fri, 5 May 2017 17:17:39 -0600 Subject: [PATCH] Add task manager, message system, more security, dozens of improvements --- action.php | 152 ++++- app.php | 53 +- database.mwb | Bin 15045 -> 15271 bytes index.php | 75 ++- lang/en_us.php | 46 ++ lang/messages.php | 20 + lib/getmsgs.php | 75 +++ lib/gettaskman.php | 140 +++++ lib/gettasks.php | 91 +++ lib/login.php | 54 ++ lib/manage.php | 25 + lib/userinfo.php | 84 +++ pages.php | 44 +- pages/edittask.php | 62 ++ pages/home.php | 13 +- pages/messages.php | 41 ++ pages/mytasks.php | 23 + pages/taskman.php | 29 + required.php | 13 +- settings.template.php | 6 + static/css/app.css | 40 ++ static/css/bootstrap-datetimepicker.min.css | 5 + static/css/easy-autocomplete.min.css | 11 + static/css/easy-autocomplete.themes.min.css | 11 + static/css/messages.css | 3 + static/js/app.js | 8 + static/js/bootstrap-datetimepicker.min.js | 217 +++++++ static/js/edittask.js | 40 ++ static/js/jquery.easy-autocomplete.min.js | 10 + static/js/messages.js | 25 + static/js/moment.min.js | 551 ++++++++++++++++++ static/js/tinymce/jquery.tinymce.min.js | 1 + static/js/tinymce/langs/readme.md | 3 + static/js/tinymce/license.txt | 504 ++++++++++++++++ .../js/tinymce/plugins/advlist/plugin.min.js | 1 + .../js/tinymce/plugins/anchor/plugin.min.js | 1 + .../js/tinymce/plugins/autolink/plugin.min.js | 1 + .../tinymce/plugins/autoresize/plugin.min.js | 1 + .../js/tinymce/plugins/autosave/plugin.min.js | 1 + .../js/tinymce/plugins/bbcode/plugin.min.js | 1 + .../js/tinymce/plugins/charmap/plugin.min.js | 1 + static/js/tinymce/plugins/code/plugin.min.js | 1 + .../tinymce/plugins/codesample/css/prism.css | 138 +++++ .../tinymce/plugins/codesample/plugin.min.js | 1 + .../tinymce/plugins/colorpicker/plugin.min.js | 1 + .../tinymce/plugins/contextmenu/plugin.min.js | 1 + .../plugins/directionality/plugin.min.js | 1 + .../plugins/emoticons/img/smiley-cool.gif | Bin 0 -> 354 bytes .../plugins/emoticons/img/smiley-cry.gif | Bin 0 -> 329 bytes .../emoticons/img/smiley-embarassed.gif | Bin 0 -> 331 bytes .../emoticons/img/smiley-foot-in-mouth.gif | Bin 0 -> 342 bytes .../plugins/emoticons/img/smiley-frown.gif | Bin 0 -> 340 bytes .../plugins/emoticons/img/smiley-innocent.gif | Bin 0 -> 336 bytes .../plugins/emoticons/img/smiley-kiss.gif | Bin 0 -> 338 bytes .../plugins/emoticons/img/smiley-laughing.gif | Bin 0 -> 343 bytes .../emoticons/img/smiley-money-mouth.gif | Bin 0 -> 321 bytes .../plugins/emoticons/img/smiley-sealed.gif | Bin 0 -> 323 bytes .../plugins/emoticons/img/smiley-smile.gif | Bin 0 -> 344 bytes .../emoticons/img/smiley-surprised.gif | Bin 0 -> 338 bytes .../emoticons/img/smiley-tongue-out.gif | Bin 0 -> 328 bytes .../emoticons/img/smiley-undecided.gif | Bin 0 -> 337 bytes .../plugins/emoticons/img/smiley-wink.gif | Bin 0 -> 350 bytes .../plugins/emoticons/img/smiley-yell.gif | Bin 0 -> 336 bytes .../tinymce/plugins/emoticons/plugin.min.js | 1 + static/js/tinymce/plugins/example/dialog.html | 8 + .../js/tinymce/plugins/example/plugin.min.js | 1 + .../plugins/example_dependency/plugin.min.js | 1 + .../js/tinymce/plugins/fullpage/plugin.min.js | 1 + .../tinymce/plugins/fullscreen/plugin.min.js | 1 + static/js/tinymce/plugins/hr/plugin.min.js | 1 + static/js/tinymce/plugins/image/plugin.min.js | 1 + .../tinymce/plugins/imagetools/plugin.min.js | 1 + .../tinymce/plugins/importcss/plugin.min.js | 1 + .../plugins/insertdatetime/plugin.min.js | 1 + .../plugins/legacyoutput/plugin.min.js | 1 + static/js/tinymce/plugins/link/plugin.min.js | 1 + static/js/tinymce/plugins/lists/plugin.min.js | 1 + static/js/tinymce/plugins/media/plugin.min.js | 1 + .../tinymce/plugins/nonbreaking/plugin.min.js | 1 + .../tinymce/plugins/noneditable/plugin.min.js | 1 + .../tinymce/plugins/pagebreak/plugin.min.js | 1 + static/js/tinymce/plugins/paste/plugin.min.js | 1 + .../js/tinymce/plugins/preview/plugin.min.js | 1 + static/js/tinymce/plugins/print/plugin.min.js | 1 + static/js/tinymce/plugins/save/plugin.min.js | 1 + .../plugins/searchreplace/plugin.min.js | 1 + .../plugins/spellchecker/plugin.min.js | 1 + .../js/tinymce/plugins/tabfocus/plugin.min.js | 1 + static/js/tinymce/plugins/table/plugin.min.js | 2 + .../js/tinymce/plugins/template/plugin.min.js | 1 + .../tinymce/plugins/textcolor/plugin.min.js | 1 + .../tinymce/plugins/textpattern/plugin.min.js | 1 + static/js/tinymce/plugins/toc/plugin.min.js | 1 + .../plugins/visualblocks/css/visualblocks.css | 135 +++++ .../plugins/visualblocks/plugin.min.js | 1 + .../tinymce/plugins/visualchars/plugin.min.js | 1 + .../tinymce/plugins/wordcount/plugin.min.js | 1 + .../skins/lightgray/content.inline.min.css | 1 + .../tinymce/skins/lightgray/content.min.css | 1 + .../skins/lightgray/fonts/tinymce-small.eot | Bin 0 -> 9492 bytes .../skins/lightgray/fonts/tinymce-small.svg | 63 ++ .../skins/lightgray/fonts/tinymce-small.ttf | Bin 0 -> 9304 bytes .../skins/lightgray/fonts/tinymce-small.woff | Bin 0 -> 9380 bytes .../tinymce/skins/lightgray/fonts/tinymce.eot | Bin 0 -> 17572 bytes .../tinymce/skins/lightgray/fonts/tinymce.svg | 131 +++++ .../tinymce/skins/lightgray/fonts/tinymce.ttf | Bin 0 -> 17408 bytes .../skins/lightgray/fonts/tinymce.woff | Bin 0 -> 17484 bytes .../js/tinymce/skins/lightgray/img/anchor.gif | Bin 0 -> 53 bytes .../js/tinymce/skins/lightgray/img/loader.gif | Bin 0 -> 2608 bytes .../js/tinymce/skins/lightgray/img/object.gif | Bin 0 -> 152 bytes .../js/tinymce/skins/lightgray/img/trans.gif | Bin 0 -> 43 bytes .../tinymce/skins/lightgray/skin.ie7.min.css | 1 + .../js/tinymce/skins/lightgray/skin.min.css | 1 + static/js/tinymce/themes/inlite/theme.min.js | 1 + static/js/tinymce/themes/modern/theme.min.js | 1 + static/js/tinymce/tinymce.min.js | 14 + 116 files changed, 2962 insertions(+), 53 deletions(-) create mode 100644 lib/getmsgs.php create mode 100644 lib/gettaskman.php create mode 100644 lib/gettasks.php create mode 100644 lib/manage.php create mode 100644 lib/userinfo.php create mode 100644 pages/edittask.php create mode 100644 pages/messages.php create mode 100644 pages/mytasks.php create mode 100644 pages/taskman.php create mode 100644 static/css/bootstrap-datetimepicker.min.css create mode 100644 static/css/easy-autocomplete.min.css create mode 100644 static/css/easy-autocomplete.themes.min.css create mode 100644 static/css/messages.css create mode 100644 static/js/bootstrap-datetimepicker.min.js create mode 100644 static/js/edittask.js create mode 100644 static/js/jquery.easy-autocomplete.min.js create mode 100644 static/js/messages.js create mode 100644 static/js/moment.min.js create mode 100644 static/js/tinymce/jquery.tinymce.min.js create mode 100644 static/js/tinymce/langs/readme.md create mode 100644 static/js/tinymce/license.txt create mode 100644 static/js/tinymce/plugins/advlist/plugin.min.js create mode 100644 static/js/tinymce/plugins/anchor/plugin.min.js create mode 100644 static/js/tinymce/plugins/autolink/plugin.min.js create mode 100644 static/js/tinymce/plugins/autoresize/plugin.min.js create mode 100644 static/js/tinymce/plugins/autosave/plugin.min.js create mode 100644 static/js/tinymce/plugins/bbcode/plugin.min.js create mode 100644 static/js/tinymce/plugins/charmap/plugin.min.js create mode 100644 static/js/tinymce/plugins/code/plugin.min.js create mode 100644 static/js/tinymce/plugins/codesample/css/prism.css create mode 100644 static/js/tinymce/plugins/codesample/plugin.min.js create mode 100644 static/js/tinymce/plugins/colorpicker/plugin.min.js create mode 100644 static/js/tinymce/plugins/contextmenu/plugin.min.js create mode 100644 static/js/tinymce/plugins/directionality/plugin.min.js create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-cool.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-cry.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-embarassed.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-frown.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-innocent.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-kiss.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-laughing.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-money-mouth.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-sealed.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-smile.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-surprised.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-tongue-out.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-undecided.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-wink.gif create mode 100644 static/js/tinymce/plugins/emoticons/img/smiley-yell.gif create mode 100644 static/js/tinymce/plugins/emoticons/plugin.min.js create mode 100644 static/js/tinymce/plugins/example/dialog.html create mode 100644 static/js/tinymce/plugins/example/plugin.min.js create mode 100644 static/js/tinymce/plugins/example_dependency/plugin.min.js create mode 100644 static/js/tinymce/plugins/fullpage/plugin.min.js create mode 100644 static/js/tinymce/plugins/fullscreen/plugin.min.js create mode 100644 static/js/tinymce/plugins/hr/plugin.min.js create mode 100644 static/js/tinymce/plugins/image/plugin.min.js create mode 100644 static/js/tinymce/plugins/imagetools/plugin.min.js create mode 100644 static/js/tinymce/plugins/importcss/plugin.min.js create mode 100644 static/js/tinymce/plugins/insertdatetime/plugin.min.js create mode 100644 static/js/tinymce/plugins/legacyoutput/plugin.min.js create mode 100644 static/js/tinymce/plugins/link/plugin.min.js create mode 100644 static/js/tinymce/plugins/lists/plugin.min.js create mode 100644 static/js/tinymce/plugins/media/plugin.min.js create mode 100644 static/js/tinymce/plugins/nonbreaking/plugin.min.js create mode 100644 static/js/tinymce/plugins/noneditable/plugin.min.js create mode 100644 static/js/tinymce/plugins/pagebreak/plugin.min.js create mode 100644 static/js/tinymce/plugins/paste/plugin.min.js create mode 100644 static/js/tinymce/plugins/preview/plugin.min.js create mode 100644 static/js/tinymce/plugins/print/plugin.min.js create mode 100644 static/js/tinymce/plugins/save/plugin.min.js create mode 100644 static/js/tinymce/plugins/searchreplace/plugin.min.js create mode 100644 static/js/tinymce/plugins/spellchecker/plugin.min.js create mode 100644 static/js/tinymce/plugins/tabfocus/plugin.min.js create mode 100644 static/js/tinymce/plugins/table/plugin.min.js create mode 100644 static/js/tinymce/plugins/template/plugin.min.js create mode 100644 static/js/tinymce/plugins/textcolor/plugin.min.js create mode 100644 static/js/tinymce/plugins/textpattern/plugin.min.js create mode 100644 static/js/tinymce/plugins/toc/plugin.min.js create mode 100644 static/js/tinymce/plugins/visualblocks/css/visualblocks.css create mode 100644 static/js/tinymce/plugins/visualblocks/plugin.min.js create mode 100644 static/js/tinymce/plugins/visualchars/plugin.min.js create mode 100644 static/js/tinymce/plugins/wordcount/plugin.min.js create mode 100644 static/js/tinymce/skins/lightgray/content.inline.min.css create mode 100644 static/js/tinymce/skins/lightgray/content.min.css create mode 100644 static/js/tinymce/skins/lightgray/fonts/tinymce-small.eot create mode 100644 static/js/tinymce/skins/lightgray/fonts/tinymce-small.svg create mode 100644 static/js/tinymce/skins/lightgray/fonts/tinymce-small.ttf create mode 100644 static/js/tinymce/skins/lightgray/fonts/tinymce-small.woff create mode 100644 static/js/tinymce/skins/lightgray/fonts/tinymce.eot create mode 100644 static/js/tinymce/skins/lightgray/fonts/tinymce.svg create mode 100644 static/js/tinymce/skins/lightgray/fonts/tinymce.ttf create mode 100644 static/js/tinymce/skins/lightgray/fonts/tinymce.woff create mode 100644 static/js/tinymce/skins/lightgray/img/anchor.gif create mode 100644 static/js/tinymce/skins/lightgray/img/loader.gif create mode 100644 static/js/tinymce/skins/lightgray/img/object.gif create mode 100644 static/js/tinymce/skins/lightgray/img/trans.gif create mode 100644 static/js/tinymce/skins/lightgray/skin.ie7.min.css create mode 100644 static/js/tinymce/skins/lightgray/skin.min.css create mode 100644 static/js/tinymce/themes/inlite/theme.min.js create mode 100644 static/js/tinymce/themes/modern/theme.min.js create mode 100644 static/js/tinymce/tinymce.min.js diff --git a/action.php b/action.php index 0ae4e7c..7204638 100644 --- a/action.php +++ b/action.php @@ -3,8 +3,11 @@ /** * Make things happen when buttons are pressed and forms submitted. */ - require_once __DIR__ . "/required.php"; +require_once __DIR__ . "/lib/login.php"; +require_once __DIR__ . "/lib/userinfo.php"; +require_once __DIR__ . "/lib/manage.php"; + dieifnotloggedin(); @@ -23,4 +26,151 @@ switch ($VARS['action']) { session_destroy(); header('Location: index.php'); die("Logged out."); + case "sendmsg": + header("HTTP/1.1 204 No Content"); + $msg = strip_tags($VARS['msg']); + if (is_empty($VARS['to'])) { + $to = null; + die(); // TODO: add some kind of permission thing to allow this + } else if (user_exists($VARS['to'])) { + $to = getUserByUsername($VARS['to'])['uid']; + } else { + die(); + } + if (is_empty($msg)) { + die(); + } + $database->insert('messages', ['messagetext' => $msg, '#messagedate' => 'NOW()', 'from' => $_SESSION['uid'], 'to' => $to]); + break; + case "delmsg": + header('HTTP/1.0 204 No Content'); + if (is_empty($VARS['msgid'])) { + die(); + } + if (!$database->has('messages', ['messageid' => $VARS['msgid']])) { + die(); + } + $msg = $database->select('messages', ['to', 'from'], ['messageid' => $VARS['msgid']])[0]; + if ($msg['to'] == $_SESSION['uid'] || + $msg['from'] == $_SESSION['uid'] || + isManagerOf($_SESSION['uid'], $msg['to']) || + isManagerOf($_SESSION['uid'], $msg['from'])) { + $database->update('messages', ['deleted' => 1], ['messageid' => $VARS['msgid']]); + } + break; + case "start": + header('HTTP/1.0 204 No Content'); + if (!$database->has('assigned_tasks', ["AND" => ['taskid' => $VARS['taskid'], 'userid' => $_SESSION['uid']]])) { + die('You are not assigned to this task!'); + } + $database->update('assigned_tasks', ['#starttime' => 'NOW()', 'statusid' => 1], ["AND" => ['taskid' => $VARS['taskid'], 'userid' => $_SESSION['uid']]]); + break; + case "finish": + header('HTTP/1.0 204 No Content'); + if (!$database->has('assigned_tasks', ["AND" => ['taskid' => $VARS['taskid'], 'userid' => $_SESSION['uid']]])) { + die('You are not assigned to this task!'); + } + $database->update('assigned_tasks', ['#endtime' => 'NOW()', 'statusid' => 2], ["AND" => ['taskid' => $VARS['taskid'], 'userid' => $_SESSION['uid']]]); + break; + case "edittask": + if (is_empty($VARS['tasktitle'])) { + header('HTTP/1.0 204 No Content'); + die(); + } + + if (is_empty($VARS['taskid'])) { + $database->insert('tasks', ['tasktitle' => $VARS['tasktitle'], 'taskdesc' => $VARS['taskdesc'], 'taskcreatoruid' => $_SESSION['uid']]); + $VARS['taskid'] = $database->id(); + header('Location: app.php?page=edittask&taskid=' . $database->id() . '&msg=task_saved'); + } else { + $database->update('tasks', ['tasktitle' => $VARS['tasktitle'], 'taskdesc' => $VARS['taskdesc']], ['taskid' => $VARS['taskid']]); + header('Location: app.php?page=edittask&taskid=' . $VARS['taskid'] . '&msg=task_saved'); + } + + if (checkIsAValidDate($VARS['taskassignedon'])) { + $assigneddate = date('Y-m-d H:i:s', strtotime($VARS['taskassignedon'])); + $database->update('tasks', ['taskassignedon' => $assigneddate], ['taskid' => $VARS['taskid']]); + } + if (checkIsAValidDate($VARS['taskdueby'])) { + $duedate = date('Y-m-d H:i:s', strtotime($VARS['taskdueby'])); + $database->update('tasks', ['taskdueby' => $duedate], ['taskid' => $VARS['taskid']]); + } + if (!is_empty($VARS['assignedto']) && user_exists($VARS['assignedto'])) { + $uid = getUserByUsername($VARS['assignedto'])['uid']; + $managed_uids = getManagedUIDs($_SESSION['uid']); + // allow self-assignment + if (!in_array($uid, $managed_uids) && $uid != $_SESSION['uid']) { + header('Location: app.php?page=edittask&taskid=' . $VARS['taskid'] . '&msg=user_not_managed'); + die(lang("user not managed", false)); + } + if ($database->has('assigned_tasks', ['taskid' => $VARS['taskid']])) { + $database->update('assigned_tasks', ['userid' => $uid, 'starttime' => null, 'endtime' => null, 'statusid' => 0], ['taskid' => $VARS['taskid']]); + } else { + $database->insert('assigned_tasks', ['taskid' => $VARS['taskid'], 'userid' => $uid, 'starttime' => null, 'endtime' => null, 'statusid' => 0]); + } + } else if (is_empty($VARS['assignedto'])) { + $database->delete('assigned_tasks', ['taskid' => $VARS['taskid']]); + } + break; + case "deltask": + if (is_empty($VARS['taskid'])) { + die('Missing taskid.'); + } + + $managed_uids = getManagedUIDs($_SESSION['uid']); + // There needs to be at least one entry otherwise the SQL query craps itself + if (count($managed_uids) < 1) { + $managed_uids = [-1]; + } + $allowed = $database->has('tasks', [ + '[>]assigned_tasks' => [ + 'taskid' => 'taskid' + ] + ], [ + "AND" => [ + "OR" => [ + 'tasks.taskcreatoruid' => $_SESSION['uid'], + 'assigned_tasks.userid' => $managed_uids + ], + "tasks.taskid" => $VARS['taskid'] + ]]); + + if (!$allowed) { + header("Location: app.php?page=taskman&msg=task_delete_not_allowed"); + die(lang("task delete not allowed", false)); + } + + if ($VARS['assigned']) { + $database->delete('assigned_tasks', ['taskid' => $VARS['taskid']]); + } else { + $database->update('tasks', ['deleted' => 1], ['taskid' => $VARS['taskid']]); + } + header("Location: app.php?page=taskman&msg=task_deleted"); + break; + case "autocomplete": + header("Content-Type: application/json"); + $client = new GuzzleHttp\Client(); + + $response = $client + ->request('POST', PORTAL_API, [ + 'form_params' => [ + 'key' => PORTAL_KEY, + 'action' => "usersearch", + 'search' => $VARS['q'] + ] + ]); + + if ($response->getStatusCode() != 200) { + exit("[]"); + } + + $resp = json_decode($response->getBody(), TRUE); + if ($resp['status'] == "OK") { + exit(json_encode($resp['result'])); + } else { + exit("[]"); + } + break; + default: + die("Invalid request."); } \ No newline at end of file diff --git a/app.php b/app.php index bf9adc1..450bd7c 100644 --- a/app.php +++ b/app.php @@ -24,13 +24,21 @@ if (!is_empty($_GET['page'])) { - + <?php echo SITE_TITLE; ?> + \n"; + } + } + ?>
@@ -44,7 +52,7 @@ if (!is_empty($_GET['page'])) { + ?>