*/ $settings = new stdClass(); // the site's name $settings->sitename = "Pepperminty Wiki"; // the url from which to fetch updates. Defaults to the master (development) branch If there is sufficient demand, a separate stable branch will be created. // note that if you use the automatic updater currently it won't save your module choices. // MAKE SURE THAT THIS POINTS TO A HTTPS URL, OTHERWISE SOMEONE COULD INJECT A VIRUS INTO YOUR WIKI $settings->updateurl = "https://raw.githubusercontent.com/sbrl/pepperminty-wiki/master/index.php"; // the secret key used to perform 'dangerous' actions, like updating the wiki, and deleting pages. It is strongly advised that you change this! // note that (semi)automatic updating of your wiki has not been added yet. $settings->sitesecret = "ed420502615bac9037f8f12abd4c9f02"; // whether people can edit the site $settings->editing = true; // the maximum number of characters allowed in a single page $settings->maxpagesize = 135000; //135,000 characters, or 50 pages // whether users who aren't logged in are allowed to edit $settings->anonedits = false; // the name of the page that will act as the home page for the wiki. This page will be served if the user didn't specify a page. $settings->defaultpage = "Main Page"; // the default action. This action will be performed if no other action is specified. $settings->defaultaction = "view"; // usernames and passwords - passwords should be hashed with sha256 $settings->users = [ "admin" => "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8", //password "user" => "873ac9ffea4dd04fa719e8920cd6938f0c23cd678af330939cff53c3d2855f34" //cheese ]; // array of usernames that are administrators. // administrators can delete and move pages, though this functionality hasn't been added yet. $settings->admins = [ "admin" ]; // The string that is prepended before an admin's name on the nav bar. defaults to a diamond shape (◆). $settings->admindisplaychar = "◆"; // contact details for the site administrator. Since user can only be added by editing this file, people will need a contact address to use to ask for an account. Displayed at the bottom of the page, and will be appropriatly obfusticated to deter spammers. $settings->admindetails = [ "name" => "Administrator", "email" => "admin@localhost" ]; // array of links and display text to display at the top of the site $settings->navlinks = [ [ "Home", "index.php" ], [ "Login", "index.php?action=login" ], " | ", "search", " | ", [ "Read", "index.php?page={page}" ], [ "Edit", "index.php?action=edit&page={page}" ], [ "Printable", "index.php?action=view&printable=yes&page={page}" ], " | ", [ $settings->admindisplaychar . "Delete", "index.php?action=delete&page={page}" ], [ $settings->admindisplaychar . "Move", "index.php?action=move&page={page}" ], " | ", [ "All Pages", "index.php?action=list" ], " | ", [ "Credits", "index.php?action=credits" ], [ "Help", "index.php?action=help" ] ]; // string of css to include // may be a url - urls will be referenced via a tag $settings->css = "body { font-family: sans-serif; color: #333333; background: #f8f8f8; } label { display: inline-block; min-width: 10rem; } textarea[name=content] { display: block; width: 100%; height: 35rem; } /*input[name=page] { width: 16rem; }*/ nav { position: absolute; top: 5px; right: 5px; } th { text-align: left; } .sitename { text-align: center; font-size: 2.5rem; color: #222222; } .footerdivider { margin-top: 4rem; }"; // the favicon // default: peppermint from https://openclipart.org/detail/19571/peppermint-candy-by-bluefrog23 $settings->favicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB3VBMVEXhERHbKCjeVVXjb2/kR0fhKirdHBziDg6qAADaHh7qLy/pdXXUNzfMAADYPj7ZPDzUNzfbHx/fERHpamrqMTHgExPdHx/bLCzhLS3fVFTjT0/ibm7kRkbiLi7aKirdISHeFBTqNDTpeHjgERHYJCTVODjYQkLaPj6/AADVOTnpbW3cIyPdFRXcJCThMjLiTU3ibW3fVVXaKyvcERH4ODj+8fH/////fHz+Fxf4KSn0UFD/CAj/AAD/Xl7/wMD/EhL//v70xMT/+Pj/iYn/HBz/g4P/IyP/Kyv/7Oz0QUH/9PT/+vr/ior/Dg7/vr7/aGj/QED/bGz/AQH/ERH/Jib/R0f/goL/0dH/qan/YWH/7e3/Cwv4R0f/MTH/enr/vLz/u7v/cHD/oKD/n5//aWn+9/f/k5P/0tL/trb/QUH/cXH/dHT/wsL/DQ3/p6f/DAz/1dX/XV3/kpL/i4v/Vlb/2Nj/9/f/pKT+7Oz/V1f/iIj/jIz/r6//Zmb/lZX/j4//T0//Dw/4MzP/GBj/+fn/o6P/TEz/xMT/b2//Tk7/OTn/HR3/hIT/ODj/Y2P/CQn/ZGT/6Oj0UlL/Gxv//f3/Bwf/YmL/6+v0w8P/Cgr/tbX0QkL+9fX4Pz/qNzd0dFHLAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfeCxINNSdmw510AAAA5ElEQVQYGQXBzSuDAQCA8eexKXOwmSZepa1JiPJxsJOrCwcnuchBjg4O/gr7D9zk4uAgJzvuMgcTpYxaUZvSm5mUj7TX7ycAqvoLIJBwStVbP0Hom1Z/ejoxrbaR1Jz6nWinbKWttGRgMSSjanPktRY6mB9WtRNTn7Ilh7LxnNpKq2/x5LnBitfz+hx0qxUaxhZ6vwqq9bx6f2XXvuUl9SVQS38NR7cvln3v15tZ9bQpuWDtZN3Lgh5DWJex3Y+z1KrVhw21+CiM74WZo83DiXq0dVBDYNJkFEU7WrwDAZhRtQrwDzwKQbT6GboLAAAAAElFTkSuQmCC"; // the prefix that should be used in the names of the session variables. // defaults to an all lower case version of the site name with all non alphanumeric characters removed // remember that changing this will log everyone out since the session varibles' name will have changed // normally you wouldn't have to change this - this setting is left over from when we used a cookie to store login details $settings->sessionprefix = preg_replace("/[^0-9a-z]/i", "", strtolower($settings->sitename)); /* Actions: view - view a page page - page name printable=[yes/no] - make output printable edit - open editor for page page - page name save - save edits to page page - page name list - list pages category - the category to list [optional] [unimplemented] login - login to the site logout - logout checklogin - check login credentials and set cookie hash - hash a string with sha256 string - string to hash help - get help update - update the wiki do - set to `true` to actually update the wiki secret - set to the value of the site's secret credits - view the credits delete - delete a page page - page name delete=yes - actually do the deletion (otherwise we display a prompt) */ /////////////////////////////////////////////////////////////////////////////////////////////// /////////////// Do not edit below this line unless you know what you are doing! /////////////// /////////////////////////////////////////////////////////////////////////////////////////////// $version = "0.5"; session_start(); ///////// Login System ///////// //clear expired sessions if(isset($_SESSION["$settings->sessionprefix-expiretime"]) and $_SESSION["$settings->sessionprefix-expiretime"] < time()) { //clear the session variables $_SESSION = []; session_destroy(); } if(!isset($_SESSION[$settings->sessionprefix . "-user"]) and !isset($_SESSION[$settings->sessionprefix . "-pass"])) { //the user is not logged in $isloggedin = false; } else { $user = $_SESSION[$settings->sessionprefix . "-user"]; $pass = $_SESSION[$settings->sessionprefix . "-pass"]; if($settings->users[$user] == $pass) { //the user is logged in $isloggedin = true; } else { //the user's login details are invalid (what is going on here?) //unset the session variables, treat them as an anonymous user, and get out of here $isloggedin = false; unset($user); unset($pass); //clear the session data $_SESSION = []; //delete al lthe variables session_destroy(); //destroy the session } } //check to see if the currently logged in user is an admin $isadmin = false; if($isloggedin) { foreach($settings->admins as $admin_username) { if($admin_username == $user) { $isadmin = true; break; } } } /////// Login System End /////// /////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////// Security and Consistency Measures //////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// if(!file_exists("./pageindex.json")) { $existingpages = glob("*.md"); $pageindex = new stdClass(); foreach($existingpages as $pagefilename) { $newentry = new stdClass(); $newentry->filename = utf8_encode($pagefilename); $newentry->size = filesize($pagefilename); $newentry->lastmodified = filemtime($pagefilename); $newentry->lasteditor = utf8_encode("unknown"); $pagekey = utf8_encode(substr($pagefilename, 0, -3)); $pageindex->$pagekey = $newentry; } file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT)); unset($existingpages); } else { $pageindex = json_decode(file_get_contents("./pageindex.json")); } /* * @summary makes a path safe * * @details paths may only contain alphanumeric characters, spaces, underscores, and dashes */ function makepathsafe($string) { return preg_replace("/[^0-9a-zA-Z\_\-\ ]/i", "", $string); } /* * @summary Hides an email address from bots by adding random html entities. * * @returns The mangled email address. */ function hide_email($str) { $hidden_email = ""; for($i = 0; $i < strlen($str); $i++) { if($str[$i] == "@") { $hidden_email .= "" . ord("@") . ";"; continue; } if(rand(0, 1) == 0) $hidden_email .= $str[$i]; else $hidden_email .= "" . ord($str[$i]) . ";"; } return $hidden_email; } //Work around an Opera + Syntastic bug where there is no margin at the left hand side if there isn't a query string when accessing a .php file if(!isset($_GET["action"]) and !isset($_GET["page"])) { http_response_code(302); header("location: index.php?action=$settings->defaultaction&page=$defaultpage"); exit(); } //make sure that the action is set if(!isset($_GET["action"])) $_GET["action"] = $settings->defaultaction; //make sure that the page is set if(!isset($_GET["page"]) or strlen($_GET["page"]) === 0) $_GET["page"] = $settings->defaultpage; //redirect the user to the safe version of the path if they entered an unsafe character if(makepathsafe($_GET["page"]) !== $_GET["page"]) { http_response_code(301); header("location: index.php?action=" . rawurlencode($_GET["action"]) . "&page=" . makepathsafe($_GET["page"])); header("x-requested-page: " . $_GET["page"]); header("x-actual-page: " . makepathsafe($_GET["page"])); exit(); } $page = $_GET["page"]; /////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////// HTML fragments ////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// class page_renderer { public static $html_template = "
From {sitename}, which is managed by {admin-details-name}.
Timed at {generation-date}
Powered by Pepperminty Wiki.
"; public static function render($title, $content, $body_template) { global $settings, $start_time; $result = self::$html_template; $result = str_replace("{body}", $body_template, $result); $result = str_replace([ "{sitename}", "{favicon-url}", "{header-html}", "{navigation-bar}", "{admin-details-name}", "{admin-details-email}", "{admins-name-list}", "{generation-date}", "{all-pages-datalist}" ], [ $settings->sitename, $settings->favicon, self::get_css_as_html(), self::render_navigation_bar(), $settings->admindetails["name"], $settings->admindetails["email"], implode(", ", $settings->admins), date("l jS \of F Y \a\\t h:ia T"), self::generate_all_pages_datalist() ], $result); $result = str_replace([ "{title}", "{content}" ], [ $title, $content ], $result); $result = str_replace("{generation-time-taken}", microtime(true) - $start_time, $result); return $result; } public static function render_main($title, $content) { return self::render($title, $content, self::$main_content_template); } public static function render_minimal($title, $content) { return self::render($title, $content, self::$minimal_content_template); } public static function get_css_as_html() { global $settings; if(preg_match("/^[^\/]*\/\/|^\//", $settings->css)) return ""; else return ""; } public static function render_navigation_bar() { global $settings, $user, $isloggedin, $page; $result = ""; return $result; } public static function render_username($name) { global $settings; $result = ""; if(in_array($name, $settings->admins)) $result .= $settings->admindisplaychar; $result .= $name; return $result; } public static function generate_all_pages_datalist() { global $pageindex; $result = ""; return $result; } } //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////// Slimdown ///////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// %slimdown% // //////////////////////////////////////////////////////////////////////////////////////////// /** * Slimdown - A very basic regex-based Markdown parser. Supports the * following elements (and can be extended via Slimdown::add_rule()): * * - Headers * - Links * - Bold * - Emphasis * - Deletions * - Quotes * - Inline code * - Blockquotes * - Ordered/unordered lists * - Horizontal rules * * Author: Johnny Broadway\1', // quote '/`(.*?)`/' => '
\1
', // inline code
'/\n\s*(\*|-)(.*)/' => 'self::ul_list', // ul lists
'/\n[0-9]+\.(.*)/' => 'self::ol_list', // ol lists
'/\n(>|\>)(.*)/' => 'self::blockquote', // blockquotes
'/\n-{3,}/' => "\n/' => "\n" // fix extra blockquote ); private static function para ($regs) { $line = $regs[1]; $trimmed = trim ($line); if (preg_match ('/^<\/?(ul|ol|li|h|p|bl)/', $trimmed)) { return "\n" . $line . "\n"; } return sprintf ("\n%s
\n", $trimmed); } private static function ul_list ($regs) { $item = $regs[2]; return sprintf ("\n\n\t
", trim($item)); } private static function ol_list ($regs) { $item = $regs[1]; return sprintf ("\n- %s
\n\n\t
", trim($item)); } private static function blockquote ($regs) { $item = $regs[2]; return sprintf ("\n- %s
\n%s", trim($item)); } private static function header ($regs) { list ($tmp, $chars, $header) = $regs; $level = strlen ($chars); return sprintf ('%s ', $level + 1, trim($header), $level + 1); } /** * Add a rule. */ public static function add_rule ($regex, $replacement) { self::$rules[$regex] = $replacement; } /** * Render some Markdown into HTML. */ public static function render ($text) { foreach (self::$rules as $regex => $replacement) { if (is_callable ( $replacement)) { $text = preg_replace_callback ($regex, $replacement, $text); } else { $text = preg_replace ($regex, $replacement, $text); } } return trim ($text); } } //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////// //////////////// Functions //////////////// /////////////////////////////////////////// //from http://php.net/manual/en/function.filesize.php#106569 //edited by Starbeamrainbowlabs function human_filesize($bytes, $decimals = 2) { $sz = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "YB", "ZB"]; $factor = floor((strlen($bytes) - 1) / 3); return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor]; } //from http://snippets.pro/snippet/137-php-convert-the-timestamp-to-human-readable-format/ function human_time_since($time) { $timediff = time() - $time; $tokens = array ( 31536000 => 'year', 2592000 => 'month', 604800 => 'week', 86400 => 'day', 3600 => 'hour', 60 => 'minute', 1 => 'second' ); foreach ($tokens as $unit => $text) { if ($timediff < $unit) continue; $numberOfUnits = floor($timediff / $unit); return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'').' ago'; } } /////////////////////////////////////////// ////////////////////////// /// Module functions /// ////////////////////////// // These functions are // // used by modules to // // register themselves // // or new pages. // ////////////////////////// $modules = []; // list that contains all the loaded modules // function to register a module function register_module($moduledata) { global $modules; //echo("registering module\n"); //var_dump($moduledata); $modules[] = $moduledata; } // function to register an action handler $actions = new stdClass(); function add_action($action_name, $func) { global $actions; //echo("adding $action_name\n"); $actions->$action_name = $func; } ////////////////////////////////////////////////////////////////// register_module([ "name" => "Password hashing action", "version" => "0.5", "author" => "Starbeamrainbowlabs", "description" => "Adds a utility action (that anyone can use) called hash that hashes a given string. Useful when changing a user's password.", "id" => "action-hash", "code" => function() { add_action("hash", function() { if(!isset($_GET["string"])) { http_response_code(422); exit(page_renderer::render_main("Missing parameter", "The
GET
parameterstring
must be specified.It is strongly recommended that you utilise this page via a private or incognito window in order to prevent your password from appearing in your browser history.
")); } else { exit(page_renderer::render_main("Hashed string", ""))); } }); } ]); register_module([ "name" => "Credits", "version" => "0.5", "author" => "Starbeamrainbowlabs", "description" => "Adds the credits page. You *must* have this module :D", "id" => "page-credits", "code" => function() { add_action("credits", function() { global $settings, $version; $title = "Credits - $settings->sitename"; $content = "
" . $_GET["string"] . "
→" . hash("sha256", $_GET["string"] . "
$settings->sitename credits
$settings->sitename is powered by Pepperminty Wiki - an entire wiki packed inside a single file, which was built by Starbeamrainbowlabs, and can be found on github (contributors will ablso be listed here in the future).
A slightly modified version of slimdown is used to parse text source into HTML. Slimdown is by Johnny Broadway, which can be found on github.
The default favicon is from Open Clipart by bluefrog23, and can be found here.
Administrators can update $settings->sitename here: Update $settings->sitename.
$settings->sitename is currently running on Pepperminty Wiki
"; exit(page_renderer::render_main($title, $content)); }); } ]); register_module([ "name" => "Page deleter", "version" => "0.5", "author" => "Starbeamrainbowlabs", "description" => "Adds an action to allow administrators to delete pages.", "id" => "page-delete", "code" => function() { add_action("delete", function() { global $pageindex, $settings, $page, $isadmin; if(!$settings->editing) { exit(page_renderer::render_main("Deleting $page - error", "$version
You tried to delete $page, but editing is disabled on this wiki.
If you wish to delete this page, please re-enable editing on this wiki first.
Nothing has been changed.
")); } if(!$isadmin) { exit(page_renderer::render_main("Deleting $page - error", "You tried to delete $page, but you are not an admin so you don't have permission to do that.
You should try logging in as an admin.
")); } if(!isset($_GET["delete"]) or $_GET["delete"] !== "yes") { exit(page_renderer::render_main("Deleting $page", "You are about to delete $page. You can't undo this!
Click here to go back.")); } unset($pageindex->$page); //delete the page from the page index file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT)); //save the new page index unlink("./$page.md"); //delete the page from the disk exit(page_renderer::render_main("Deleting $page - $settings->sitename", "
$page has been deleted. Go back to the main page.
")); }); } ]); register_module([ "name" => "Page editor", "version" => "0.6", "author" => "Starbeamrainbowlabs", "description" => "Allows you to edit pages by adding the edit and save actions. You should probably include this one.", "id" => "page-edit", "code" => function() { /* * * ___ __ ___ _____ * / __|/ _` \ \ / / _ \ * \__ \ (_| |\ V / __/ * |___/\__,_| \_/ \___| * %save% */ add_action("edit", function() { global $pageindex, $settings, $page, $isloggedin; $filename = "$page.md"; $creatingpage = !isset($pageindex->$page); if((isset($_GET["newpage"]) and $_GET["newpage"] == "true") or $creatingpage) { $title = "Creating $page"; } else { $title = "Editing $page"; } $pagetext = ""; if(isset($pageindex->$page)) { $pagetext = file_get_contents($filename); } if((!$isloggedin and !$settings->anonedits) or !$settings->editing) { if(!$creatingpage) { //the page already exists - let the user view the page source exit(page_renderer::render_main("Viewing source for $page", "$settings->sitename does not allow anonymous users to make edits. You can view the source of $page below, but you can't edit it.
")); } else { http_response_code(404); exit(page_renderer::render_main("404 - $page", "The page
$page
does not exist, but you do not have permission to create it.If you haven't already, perhaps you should try logging in.
")); } } $content = "$title
"; if(!$isloggedin and $settings->anonedits) { $content .= "Warning: You are not logged in! Your IP address may be recorded.
"; } $content .= ""; exit(page_renderer::render_main("$title - $settings->sitename", $content)); }); /* * _ _ _ * ___ __| (_) |_ * / _ \/ _` | | __| * | __/ (_| | | |_ * \___|\__,_|_|\__| * %edit% */ add_action("save", function() { global $pageindex, $settings, $page, $isloggedin, $user; if(!$settings->editing) { header("location: index.php?page=$page"); exit(page_renderer::render_main("Error saving edit", "Editing is currently disabled on this wiki.
")); } if(!$isloggedin and !$settings->anonedits) { http_response_code(403); header("refresh: 5; url=index.php?page=$page"); exit("You are not logged in, so you are not allowed to save pages on $settings->sitename. Redirecting in 5 seconds...."); } if(!isset($_POST["content"])) { http_response_code(400); header("refresh: 5; url=index.php?page=$page"); exit("Bad request: No content specified."); } if(file_put_contents("$page.md", htmlentities($_POST["content"]), ENT_QUOTES) !== false) { //update the page index if(!isset($pageindex->$page)) { $pageindex->$page = new stdClass(); $pageindex->$page->filename = "$page.md"; } $pageindex->$page->size = strlen($_POST["content"]); $pageindex->$page->lastmodified = time(); if($isloggedin) $pageindex->$page->lasteditor = utf8_encode($user); else $pageindex->$page->lasteditor = utf8_encode("anonymous"); file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT)); if(isset($_GET["newpage"])) http_response_code(201); else http_response_code(200); header("location: index.php?page=$page&edit_status=success"); exit(); } else { http_response_code(507); exit(page_renderer::render_main("Error saving page - $settings->sitename", "$settings->sitename failed to write your changes to the disk. Your changes have not been saved, but you might be able to recover your edit by pressing the back button in your browser.
Please tell the administrator of this wiki (" . $settings->admindetails["name"] . ") about this problem.
")); } }); } ]); register_module([ "name" => "Help page", "version" => "0.5", "author" => "Starbeamrainbowlabs", "description" => "Adds the help action. You really want this one.", "id" => "page-help", "code" => function() { add_action("help", function() { global $settings, $version; $title = "Help - $settings->sitename"; $content = "$settings->sitename Help
Welcome to $settings->sitename!
$settings->sitename is powered by Pepperminty wiki, a complete wiki in a box you can drop into your server.
Navigating
All the navigation links can be found in the top right corner, along with a box in which you can type a page name and hit enter to be taken to that page (if your site administrator has enabled it).
In order to edit pages on $settings->sitename, you probably need to be logged in. If you do not already have an account you will need to ask $settings->sitename's administrator for an account since there is not registration form. Note that the $settings->sitename's administrator may have changed these settings to allow anonymous edits.
Editing
$settings->sitename's editor uses a modified version of slimdown, a flavour of markdown that is implementated using regular expressions. See the credits page for more information and links to the original source for this. A quick reference can be found below:
Type This To get this _italics_
italics *bold*
bold # Heading
Heading
## Sub Heading
Sub Heading
[[Internal Link]]
Internal Link [[Display Text|Internal Link]]
Display Text [Display text](//google.com/)
Display Text ~~Strikethrough~~
Strikethough> Blockquote
> Some text Blockquote
Some text---
- One - Two - Three
- One
- Two
- Three
Administrator Actions
By default, the
delete
andmove
actions are shown on the nav bar. These can be used by administrators to delete or move pages.The other thing admininistrators can do is update the wiki (provided they know the site's secret). This page can be found here: Update $settings->sitename.
$settings->sitename is currently running on Pepperminty Wiki
"; exit(page_renderer::render_main($title, $content)); }); } ]); register_module([ "name" => "Page list", "version" => "0.5", "author" => "Starbeamrainbowlabs", "description" => "Adds a page that lists all the pages in the index along with their metadata.", "id" => "page-list", "code" => function() { add_action("list", function() { global $pageindex, $settings; $title = "All Pages"; $content = "$version
$title on $settings->sitename
"; exit(page_renderer::render_main("$title - $settings->sitename", $content)); }); } ]); register_module([ "name" => "Login", "version" => "0.5", "author" => "Starbeamrainbowlabs", "description" => "Adds a pair of actions (login and checklogin) that allow users to login. You need this one if you want your users to be able to login.", "id" => "page-login", "code" => function() { /* * _ _ * | | ___ __ _(_)_ __ * | |/ _ \ / _` | | '_ \ * | | (_) | (_| | | | | | * |_|\___/ \__, |_|_| |_| * |___/ %login% */ add_action("login", function() { global $settings; $title = "Login to $settings->sitename"; $content = "
\n"; foreach($pageindex as $pagename => $pagedetails) { $content .= "\t\t Page Name Size Last Editor Last Edit Time \n"; } $content .= " $pagename " . human_filesize($pagedetails->size) . " $pagedetails->lasteditor " . human_time_since($pagedetails->lastmodified) . " (" . date("l jS \of F Y \a\\t h:ia T", $pagedetails->lastmodified) . ") Login to $settings->sitename
\n"; if(isset($_GET["failed"])) $content .= "\t\tLogin failed.
\n"; $content .= "\t\t"; exit(page_renderer::render_main($title, $content)); }); /* * _ _ _ _ * ___| |__ ___ ___| | _| | ___ __ _(_)_ __ * / __| '_ \ / _ \/ __| |/ / |/ _ \ / _` | | '_ \ * | (__| | | | __/ (__| <| | (_) | (_| | | | | | * \___|_| |_|\___|\___|_|\_\_|\___/ \__, |_|_| |_| * %checklogin% |___/ */ add_action("checklogin", function() { global $settings; //actually do the login if(isset($_POST["user"]) and isset($_POST["pass"])) { //the user wants to log in $user = $_POST["user"]; $pass = $_POST["pass"]; if($settings->users[$user] == hash("sha256", $pass)) { $isloggedin = true; $expiretime = time() + 60*60*24*30; //30 days from now $_SESSION["$settings->sessionprefix-user"] = $user; $_SESSION["$settings->sessionprefix-pass"] = hash("sha256", $pass); $_SESSION["$settings->sessionprefix-expiretime"] = $expiretime; //redirect to wherever the user was going http_response_code(302); if(isset($_POST["goto"])) header("location: " . $_POST["returnto"]); else header("location: index.php"); exit(); } else { http_response_code(302); header("location: index.php?action=login&failed=yes"); exit(); } } else { http_response_code(302); header("location: index.php?action=login&failed=yes&badrequest=yes"); exit(); } }); } ]); register_module([ "name" => "Logout", "version" => "0.5", "author" => "Starbeamrainbowlabs", "description" => "Adds an action to let users user out. For security reasons it is wise to add this module since logging in automatically opens a session that is valid for 30 days.", "id" => "page-logout", "code" => function() { add_action("logout", function() { global $user, $pass, $isloggedin; $isloggedin = false; unset($user); unset($pass); //clear the session variables $_SESSION = []; session_destroy(); exit(page_renderer::render_main("Logout Successful", "Logout Successful
Logout Successful. You can login again here.
")); }); } ]); register_module([ "name" => "Page mover", "version" => "0.5", "author" => "Starbeamrainbowlabs", "description" => "Adds an action to allow administrators to move pages.", "id" => "page-move", "code" => function() { add_action("move", function() { global $pageindex, $settings, $page, $isadmin; if(!$settings->editing) { exit(page_renderer::render_main("Moving $page - error", "You tried to move $page, but editing is disabled on this wiki.
If you wish to move this page, please re-enable editing on this wiki first.
Nothing has been changed.
")); } if(!$isadmin) { exit(page_renderer::render_main("Moving $page - Error", "You tried to move $page, but you do not have permission to do that.
You should try logging in as an admin.
")); } if(!isset($_GET["new_name"]) or strlen($_GET["new_name"]) == 0) exit(page_renderer::render_main("Moving $page", "Moving $page
")); $new_name = makepathsafe($_GET["new_name"]); if(!isset($pageindex->$page)) exit(page_renderer::render_main("Moving $page - Error", "You tried to move $page to $new_name, but the page with the name $page does not exist in the first place.
Nothing has been changed.
")); if($page == $new_name) exit(page_renderer::render_main("Moving $page - Error", "You tried to move $page, but the new name you gave is the same as it's current name.
It is possible that you tried to use some characters in the new name that are not allowed and were removed.
Page names may only contain alphanumeric characters, dashes, and underscores.
")); //move the page in the page index $pageindex->$new_name = new stdClass(); foreach($pageindex->$page as $key => $value) { $pageindex->$new_name->$key = $value; } unset($pageindex->$page); file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT)); //move the page on the disk rename("$page.md", "$new_name.md"); exit(page_renderer::render_main("Moving $page", "$page has been moved to $new_name successfully.
")); }); } ]); register_module([ "name" => "Update", "version" => "0.6", "author" => "Starbeamrainbowlabs", "description" => "Adds an update page that downloads the latest stable version of Pepperminty Wiki. This module is currently outdated as it doesn't save your module preferences.", "id" => "page-update", "code" => function() { add_action("update", function() { global $settings, $isadmin; if(!$isadmin) { http_response_code(401); exit(page_renderer::render_main("Update - Error", "You must be an administrator to do that.
")); } if(!isset($_GET["do"]) or $_GET["do"] !== "true") { exit(page_renderer::render_main("Update $settings->sitename", "This page allows you to update $settings->sitename.
Currently, $settings->sitename is using $settings->version of Pepperminty Wiki.
This script will automatically download and install the latest version of Pepperminty Wiki from the url of your choice (see settings), regardless of whether an update is actually needed (version checking isn't implemented yet).
To update $settings->sitename, fill out the form below and click click the update button.
Note that a backup system has not been implemented yet! If this script fails you will loose your wiki's code and have to re-build it.
")); } if(!isset($_GET["secret"]) or $_GET["secret"] !== $settings->sitesecret) { exit(page_renderer::render_main("Update $settings->sitename - Error", "You forgot to enter $settings->sitename's secret code or entered it incorrectly. $settings->sitename's secret can be found in the settings portion of
")); } $settings_separator = "/////////////// Do not edit below this line unless you know what you are doing! ///////////////"; $log = "Beginning update...\n"; $log .= "I amindex.php
." . __FILE__ . "
.\n"; $oldcode = file_get_contents(__FILE__); $log .= "Fetching new code..."; $newcode = file_get_contents($settings->updateurl); $log .= "done.\n"; $log .= "Rewriting" . __FILE__ . "
..."; $settings = substr($oldcode, 0, strpos($oldcode, $settings_separator)); $code = substr($newcode, strpos($newcode, $settings_separator)); $result = $settings . $code; $log .= "done.\n"; $log .= "Saving..."; file_put_contents(__FILE__, $result); $log .= "done.\n"; $log .= "Update complete. I am now running on the latest version of Pepperminty Wiki."; $log .= "The version number that I have updated to can be found on the credits or help ages."; exit(page_renderer::render_main("Update - Success", "")); }); } ]); register_module([ "name" => "Page viewer", "version" => "0.6", "author" => "Starbeamrainbowlabs", "description" => "Allows you to view pages. You should include this one.", "id" => "page-view", "code" => function() { add_action("view", function() { global $pageindex, $settings, $page; //check to make sure that the page exists if(!isset($pageindex->$page)) { // todo make this intelligent so we only redirect if the user is acutally able to create the page if($settings->editing) { //editing is enabled, redirect to the editing page http_response_code(307); //temporary redirect header("location: index.php?action=edit&newpage=yes&page=" . rawurlencode($page)); exit(); } else { //editing is disabled, show an error message http_response_code(404); exit(page_renderer::render_main("$page - 404 - $settings->sitename", "
- " . implode("
- ", explode("\n", $log)) . "
$page does not exist.
Since editing is currently disabled on this wiki, you may not create this page. If you feel that this page should exist, try contacting this wiki's Administrator.
")); } } $title = "$page - $settings->sitename"; $content = "$page
"; $slimdown_start = microtime(true); $content .= Slimdown::render(file_get_contents("$page.md")); $content .= "\n\t\n"; if(isset($_GET["printable"]) and $_GET["printable"] === "yes") exit(page_renderer::render_minimal($title, $content)); else exit(page_renderer::render_main($title, $content)); }); } ]); // %next_module% // // execute each module's code foreach($modules as $moduledata) { $moduledata["code"](); } // make sure that the credits page exists if(!isset($actions->credits)) { exit(page_renderer::render_main("Error - $settings->$sitename", "No credits page detected. The credits page is a required module!
")); } // Perform the appropriate action $action_name = strtolower($_GET["action"]); if(isset($actions->$action_name)) { $req_action_data = $actions->$action_name; $req_action_data(); } else { exit(page_renderer::render_main("Error - $settings->sitename", "No action called " . strtolower($_GET["action"]) ." has been registered. Perhaps you are missing a module?
")); } ?>