From 0622400d0c9e07d1a597069730754c8781a80b6a Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sat, 18 Apr 2020 12:37:07 +0100 Subject: [PATCH] fix whitespace --- modules/feature-upload.php | 153 ++++++++++++++++++------------------- modules/page-login.php | 68 ++++++++--------- 2 files changed, 109 insertions(+), 112 deletions(-) diff --git a/modules/feature-upload.php b/modules/feature-upload.php index 622a003..aec14f0 100644 --- a/modules/feature-upload.php +++ b/modules/feature-upload.php @@ -14,8 +14,8 @@ register_module([ * @apiPermission User * * @apiParam {bool} avatar Optional. If true then a special page to upload your avatar is displayed instead. - */ - + */ + /** * @api {post} ?action=upload Upload a file * @apiName UploadFile @@ -35,7 +35,7 @@ register_module([ * @apiError DuplicateFileError The filename specified is a duplicate of a file that already exists. * @apiError FileTamperedError Pepperminty Wiki couldn't verify that the file wasn't tampered with during theupload process. */ - + /* * ██ ██ ██████ ██ ██████ █████ ██████ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ @@ -45,20 +45,20 @@ register_module([ */ add_action("upload", function() { global $settings, $env, $pageindex, $paths; - + $is_avatar = !empty($_POST["avatar"]) || !empty($_GET["avatar"]); - + switch($_SERVER["REQUEST_METHOD"]) { case "GET": // Send upload page - + if(!$settings->upload_enabled) exit(page_renderer::render("Upload Disabled - $setting->sitename", "

You can't upload anything at the moment because $settings->sitename has uploads disabled. Try contacting $settings->admindetails_name, your site Administrator. Go back.

")); if(!$env->is_logged_in) exit(page_renderer::render("Upload Error - $settings->sitename", "

You are not currently logged in, so you can't upload anything.

Try logging in first.

")); - + if($is_avatar) { exit(page_renderer::render("Upload avatar - $settings->sitename", "

Upload avatar

Select an image below, and then press upload. $settings->sitename currently supports the following file types (though not all of them may be suitable for an avatar): " . implode(", ", $settings->upload_allowed_file_types) . "

@@ -66,13 +66,13 @@ register_module([
- +

$settings->editing_message

")); } - + exit(page_renderer::render("Upload - $settings->sitename", "

Upload file

Select an image or file below, and then type a name for it in the box. This server currently supports uploads up to " . human_filesize(get_max_upload_size()) . " in size.

$settings->sitename currently supports uploading of the following file types: " . implode(", ", $settings->upload_allowed_file_types) . ".

@@ -95,16 +95,16 @@ register_module([ document.getElementById('file-upload-name').value = newName; }); ")); - + break; - + case "POST": // Receive file - + if(!$settings->editing) { exit(page_renderer::render_main("Upload failed - $settings->sitename", "

Your upload couldn't be processed because editing is currently disabled on $settings->sitename. Please contact $settings->admindetails_name, $settings->sitename's administrator for more information - their contact details can be found at the bottom of this page. Go back to the main page.")); } - + // Make sure uploads are enabled if(!$settings->upload_enabled) { @@ -113,7 +113,7 @@ register_module([ http_response_code(412); exit(page_renderer::render("Upload failed - $settings->sitename", "

Your upload couldn't be processed because uploads are currently disabled on $settings->sitename. Go back to the main page.

")); } - + // Make sure that the user is logged in if(!$env->is_logged_in) { @@ -122,7 +122,7 @@ register_module([ http_response_code(401); exit(page_renderer::render("Upload failed - $settings->sitename", "

Your upload couldn't be processed because you are not logged in.

Try logging in first.")); } - + // Check for php upload errors if($_FILES["file"]["error"] > 0) { @@ -135,16 +135,16 @@ register_module([ exit(page_renderer::render("Upload failed - $settings->sitename", "

Your upload couldn't be processed because " . (($_FILES["file"]["error"] == 1 || $_FILES["file"]["error"] == 2) ? "the file is too large" : "an error occurred") . ".

Please contact $settings->admindetails_name, $settings->sitename's administrator for help.

")); } - + // Calculate the target name, removing any characters we // are unsure about. $target_name = makepathsafe($_POST["name"] ?? "Users/$env->user/Avatar"); $temp_filename = $_FILES["file"]["tmp_name"]; - + $mimechecker = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($mimechecker, $temp_filename); finfo_close($mimechecker); - + if(!in_array($mime_type, $settings->upload_allowed_file_types)) { http_response_code(415); @@ -152,20 +152,20 @@ register_module([

The file you tried to upload appeared to be of type $mime_type, but $settings->sitename currently only allows the uploading of the following file types: " . implode(", ", $settings->upload_allowed_file_types) . ".

Go back to the Main Page.

")); } - + // Perform appropriate checks based on the *real* filetype if($is_avatar && substr($mime_type, 0, strpos($mime_type, "/")) !== "image") { http_response_code(415); exit(page_renderer::render_main("Error uploading avatar - $settings->sitename", "

That file appears to be unsuitable as an avatar, as $settings->sitename has detected it to be of type $mime_type, which doesn't appear to be an image. Please try uploading a different file to use as your avatar.

")); } - + switch(substr($mime_type, 0, strpos($mime_type, "/"))) { case "image": $extra_data = []; // Check SVG uploads with a special function $imagesize = $mime_type !== "image/svg+xml" ? getimagesize($temp_filename, $extra_data) : upload_check_svg($temp_filename); - + // Make sure that the image size is defined if(!is_int($imagesize[0]) or !is_int($imagesize[1])) { @@ -175,41 +175,41 @@ register_module([ } break; } - + $file_extension = system_mime_type_extension($mime_type); - + // Override the detected file extension if a file extension // is explicitly specified in the settings if(isset($settings->mime_mappings_overrides->$mime_type)) $file_extension = $settings->mime_mappings_overrides->$mime_type; - + if(in_array($file_extension, [ "php", ".htaccess", "asp", "aspx" ])) { http_response_code(415); exit(page_renderer::render("Upload Error - $settings->sitename", "

The file you uploaded appears to be dangerous and has been discarded. Please contact $settings->sitename's administrator for assistance.

Additional information: The file uploaded appeared to be of type $mime_type, which mapped onto the extension $file_extension. This file extension has the potential to be executed accidentally by the web server.

")); } - + // Rewrite the name to include the _actual_ file extension we've cleverly calculated :D - + // The path to the place (relative to the wiki data root) // that we're actually going to store the uploaded file itself $new_filename = "$paths->upload_file_prefix$target_name$file_extension"; // The path (relative, as before) to the description file $new_description_filename = "$new_filename.md"; - + // The page path that the new file will be stored under $new_pagepath = $new_filename; - + // Rewrite the paths to store avatars in the right place if($is_avatar) { $new_pagepath = $target_name; $new_filename = "$target_name.$file_extension"; } - + if(isset($pageindex->$new_pagepath) && !$is_avatar) exit(page_renderer::render("Upload Error - $settings->sitename", "

A page or file has already been uploaded with the name '$new_filename'. Try deleting it first. If you do not have permission to delete things, try contacting one of the moderators.

")); - + // Delete the previously uploaded avatar, if it exists // In the future we _may_ not need this once we have // file history online. @@ -219,21 +219,21 @@ register_module([ // Make sure that the palce we're uploading to exists if(!file_exists(dirname($env->storage_prefix . $new_filename))) mkdir(dirname($env->storage_prefix . $new_filename), 0775, true); - + if(!move_uploaded_file($temp_filename, $env->storage_prefix . $new_filename)) { http_response_code(409); exit(page_renderer::render("Upload Error - $settings->sitename", "

The file you uploaded was valid, but $settings->sitename couldn't verify that it was tampered with during the upload process. This probably means that either is a configuration error, or that $settings->sitename has been attacked. Please contact " . $settings->admindetails_name . ", your $settings->sitename Administrator.

")); } - + $description = $_POST["description"] ?? "_(No description provided)_\n"; - + // Escape the raw html in the provided description if the setting is enabled if($settings->clean_raw_html) $description = htmlentities($description, ENT_QUOTES); - + file_put_contents($env->storage_prefix . $new_description_filename, $description); - + // Construct a new entry for the pageindex $entry = new stdClass(); // Point to the description's filepath since this property @@ -249,17 +249,17 @@ register_module([ // Assign the new entry to the image's filepath as that // should be the page name. $pageindex->$new_pagepath = $entry; - + // Generate a revision to keep the page history up to date if(module_exists("feature-history")) { $oldsource = ""; // Only variables can be passed by reference, not literals history_add_revision($entry, $description, $oldsource, false); } - + // Save the pageindex save_pageindex(); - + if(module_exists("feature-recent-changes")) { add_recent_change([ @@ -270,13 +270,13 @@ register_module([ "filesize" => filesize($env->storage_prefix . $entry->uploadedfilepath) ]); } - + header("location: ?action=view&page=$new_pagepath&upload=success"); - + break; } }); - + /** * @api {get} ?action=preview&page={pageName}[&size={someSize}] Get a preview of a file * @apiName PreviewFile @@ -289,7 +289,7 @@ register_module([ * @apiError PreviewNoFileError No file was found associated with the specified page. * @apiError PreviewUnknownFileTypeError Pepperminty Wiki was unable to generate a preview for the requested file's type. */ - + /* * ██████ ██████ ███████ ██ ██ ██ ███████ ██ ██ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ @@ -299,7 +299,7 @@ register_module([ */ add_action("preview", function() { global $settings, $env, $pageindex, $start_time; - + if(empty($pageindex->{$env->page}->uploadedfilepath)) { $im = errorimage("The page '$env->page' doesn't have an associated file."); @@ -307,14 +307,14 @@ register_module([ imagepng($im); exit(); } - + $filepath = realpath($env->storage_prefix . $pageindex->{$env->page}->uploadedfilepath); $mime_type = $pageindex->{$env->page}->uploadedfilemime; $shortFilename = substr($filepath, 1 + (strrpos($filepath, '/') !== false ? strrpos($filepath, '/') : -1)); - + header("content-disposition: inline; filename=\"$shortFilename\""); header("last-modified: " . gmdate('D, d M Y H:i:s T', $pageindex->{$env->page}->lastmodified)); - + // If the size is set to original, then send (or redirect to) the original image // Also do the same for SVGs if svg rendering is disabled. if(isset($_GET["size"]) and $_GET["size"] == "original" or @@ -322,18 +322,18 @@ register_module([ { // Get the file size $filesize = filesize($filepath); - + // Send some headers header("content-length: $filesize"); header("content-type: $mime_type"); - + // Open the file and send it to the user $handle = fopen($filepath, "rb"); fpassthru($handle); fclose($handle); exit(); } - + // Determine the target size of the image $target_size = 512; if(isset($_GET["size"])) @@ -342,23 +342,20 @@ register_module([ $target_size = $settings->min_preview_size; if($target_size > $settings->max_preview_size) $target_size = $settings->max_preview_size; - + // Determine the output file type $output_mime = $settings->preview_file_type; if(isset($_GET["type"]) and in_array($_GET["type"], [ "image/png", "image/jpeg", "image/webp" ])) $output_mime = $_GET["type"]; - + /// ETag handling /// // Generate the etag and send it to the client $preview_etag = sha1("$output_mime|$target_size|$filepath|$mime_type"); $allheaders = getallheaders(); $allheaders = array_change_key_case($allheaders, CASE_LOWER); if(!isset($allheaders["if-none-match"])) - { header("etag: $preview_etag"); - } - else - { + else { if($allheaders["if-none-match"] === $preview_etag) { http_response_code(304); @@ -367,24 +364,24 @@ register_module([ } } /// ETag handling end /// - + /* Disabled until we work out what to do about caching previews * $previewFilename = "$filepath.preview.$outputFormat"; if($target_size === $settings->default_preview_size) { // The request is for the default preview size // Check to see if we have a preview pre-rendered - + } */ - + $preview = new Imagick(); switch(substr($mime_type, 0, strpos($mime_type, "/"))) { case "image": $preview->readImage($filepath); break; - + case "application": if($mime_type == "application/pdf") { @@ -394,7 +391,7 @@ register_module([ $preview->setImageColorspace(255); break; } - + case "video": case "audio": if($settings->data_storage_dir == ".") @@ -408,18 +405,18 @@ register_module([ // TODO: Add support for ranges here. // Get the file size $filesize = filesize($filepath); - + // Send some headers header("content-length: $filesize"); header("content-type: $mime_type"); - + // Open the file and send it to the user $handle = fopen($filepath, "rb"); fpassthru($handle); fclose($handle); exit(); break; - + default: http_response_code(501); $preview = errorimage("Unrecognised file type '$mime_type'.", $target_size); @@ -427,10 +424,10 @@ register_module([ imagepng($preview); exit(); } - + // Scale the image down to the target size $preview->resizeImage($target_size, $target_size, imagick::FILTER_LANCZOS, 1, true); - + // Send the completed preview image to the user header("content-type: $output_mime"); header("x-generation-time: " . (microtime(true) - $start_time) . "s"); @@ -443,7 +440,7 @@ register_module([ file_put_contents($previewFilename, $preview->getImageBlob()); */ }); - + /* * ██████ ██████ ███████ ██ ██ ██ ███████ ██ ██ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ @@ -462,7 +459,7 @@ register_module([ // Don't do anything if the action isn't view if($env->action !== "view") return; - + if(isset($pageindex->{$env->page}->uploadedfile) and $pageindex->{$env->page}->uploadedfile == true) { // We are looking at a page that is paired with an uploaded file @@ -474,7 +471,7 @@ register_module([ $originalUrl = $env->storage_prefix == "./" ? $filepath : "?action=preview&size=original&page=" . rawurlencode($env->page); if($mime_type == "application/pdf") $fileTypeDisplay = "pdf"; - + $preview_html = ""; switch($fileTypeDisplay) { @@ -494,29 +491,29 @@ register_module([ } $preview_html .= "\n\t\t\t"; break; - + case "video": $preview_html .= "\t\t\t
"; break; - + case "audio": $preview_html .= "\t\t\t
"; break; - + case "pdf": $preview_html .= "\t\t\t"; break; - + default: $preview_html .= "\t\t\t

No preview is available, but you can download it instead:

Download"; break; } - + $fileInfo = []; $fileInfo["Name"] = str_replace("Files/", "", $filepath); $fileInfo["Type"] = $mime_type; @@ -530,7 +527,7 @@ register_module([ } $fileInfo["Uploaded by"] = $pageindex->{$env->page}->lasteditor; $fileInfo["Short markdown embed code"] = " "; - + $preview_html .= "\t\t\t

File Information

"; foreach ($fileInfo as $displayName => $displayValue) @@ -538,11 +535,11 @@ register_module([ $preview_html .= "\n"; } $preview_html .= "
$displayName$displayValue
"; - + $parts["{content}"] = str_replace("", "\n$preview_html", $parts["{content}"]); } }); - + // Add the snippet that copies the embed markdown code to the clipboard page_renderer::add_js_snippet('window.addEventListener("load", function(event) { let button = document.querySelector(".short-embed-markdown-button"); @@ -553,7 +550,7 @@ register_module([ button.innerHTML = document.execCommand("copy") ? "Copied!" : "Failed to copy :-("; }); });'); - + // Register a section on the help page on uploading files add_help_section("28-uploading-files", "Uploading Files", "

$settings->sitename supports the uploading of files, though it is up to " . $settings->admindetails_name . ", $settings->sitename's administrator as to whether it is enabled or not (uploads are currently " . (($settings->upload_enabled) ? "enabled" : "disabled") . ").

Currently Pepperminty Wiki (the software that $settings->sitename uses) only supports the uploading of images, videos, and audio, although more file types should be supported in the future (open an issue on GitHub if you are interested in support for more file types).

@@ -652,7 +649,7 @@ function getsvgsize($svgFilename) $imageSize = [ intval($rootAttrs->width), intval($rootAttrs->height) ]; else if(isset($rootAttrs->viewBox)) $imageSize = array_map("intval", array_slice(explode(" ", $rootAttrs->viewBox), -2, 2)); - + return $imageSize; } diff --git a/modules/page-login.php b/modules/page-login.php index 45890b3..39bcf55 100644 --- a/modules/page-login.php +++ b/modules/page-login.php @@ -7,7 +7,7 @@ register_module([ "id" => "page-login", "code" => function() { global $settings; - + /** * @api {get} ?action=login[&failed=yes][&returnto={someUrl}] Get the login page * @apiName Login @@ -17,7 +17,7 @@ register_module([ * @apiParam {string} failed Setting to yes causes a login failure message to be displayed above the login form. * @apiParam {string} returnto Set to the url to redirect to upon a successful login. */ - + /* * ██ ██████ ██████ ██ ███ ██ * ██ ██ ██ ██ ██ ████ ██ @@ -27,18 +27,18 @@ register_module([ */ add_action("login", function() { global $settings, $env; - + // Build the action url that will actually perform the login $login_form_action_url = "index.php?action=checklogin"; if(isset($_GET["returnto"])) $login_form_action_url .= "&returnto=" . rawurlencode($_GET["returnto"]); - + if($env->is_logged_in && !empty($_GET["returnto"])) { http_response_code(307); header("location: " . $_GET["returnto"]); } - + $title = "Login to $settings->sitename"; $content = "

Login to $settings->sitename

\n"; if(isset($_GET["failed"])) @@ -56,7 +56,7 @@ register_module([ \n"; exit(page_renderer::render_main($title, $content)); }); - + /** * @api {post} ?action=checklogin Perform a login * @apiName CheckLogin @@ -69,7 +69,7 @@ register_module([ * * @apiError InvalidCredentialsError The supplied credentials were invalid. Note that this error is actually a redirect to ?action=login&failed=yes (with the returnto parameter appended if you supplied one) */ - + /* * ██████ ██ ██ ███████ ██████ ██ ██ * ██ ██ ██ ██ ██ ██ ██ @@ -85,7 +85,7 @@ register_module([ */ add_action("checklogin", function() { global $settings, $env; - + if(!isset($_POST["user"]) or !isset($_POST["pass"])) { http_response_code(302); $nextUrl = "index.php?action=login&failed=yes&badrequest=yes"; @@ -94,13 +94,13 @@ register_module([ header("location: $nextUrl"); exit(); } - + // Actually do the login - + // The user wants to log in $user = $_POST["user"]; $pass = $_POST["pass"]; - + // Verify their password if(empty($settings->users->$user) || !verify_password($pass, $settings->users->$user->password)) { // Login failed :-( @@ -112,16 +112,16 @@ register_module([ header("location: $nextUrl"); exit(); } - + // Success! :D - + // Update the environment $env->is_logged_in = true; $env->user = $user; $env->user_data = $settings->users->{$env->user}; - + $new_password_hash = hash_password_update($pass, $settings->users->$user->password); - + // Update the password hash if($new_password_hash !== null) { $env->user_data->password = $new_password_hash; @@ -132,18 +132,18 @@ register_module([ } error_log("[Pepperminty Wiki] Updated password hash for $user."); } - + // If the email address is still in the old field, migrate it if(!empty($settings->users->{$user}->email)) { $settings->users->{$user}->emailAddress = $settings->users->{$user}->email; unset($settings->users->{$user}->email); save_settings(); } - + $_SESSION["$settings->sessionprefix-user"] = $user; $_SESSION["$settings->sessionprefix-pass"] = $new_password_hash ?? hash_password($pass); $_SESSION["$settings->sessionprefix-expiretime"] = time() + 60*60*24*30; // 30 days from now - + // Redirect to wherever the user was going http_response_code(302); header("x-login-success: yes"); @@ -153,34 +153,34 @@ register_module([ header("location: index.php"); exit(); }); - + add_action("hash-cost-test", function() { global $env; - + header("content-type: text/plain"); - + if(!$env->is_logged_in || !$env->is_admin) { http_response_code(401); exit("Error: Only moderators are allowed to use this action."); } - + $time_compute = microtime(true); $cost = hash_password_compute_cost(true); $time_compute = (microtime(true) - $time_compute)*1000; - + $time_cost = microtime(true); password_hash("testing", PASSWORD_DEFAULT, [ "cost" => $cost ]); $time_cost = (microtime(true) - $time_cost)*1000; - + echo("Calculated cost: $cost ({$time_cost}ms)\n"); echo("Time taken: {$time_compute}ms\n"); exit(date("r")); }); - + // Register a section on logging in on the help page. add_help_section("30-login", "Logging in", "

In order to edit $settings->sitename and have your edit attributed to you, you need to be logged in. Depending on the settings, logging in may be a required step if you want to edit at all. Thankfully, loggging in is not hard. Simply click the "Login" link in the top left, type your username and password, and then click login.

If you do not have an account yet and would like one, try contacting $settings->admindetails_name, $settings->sitename's administrator and ask them nicely to see if they can create you an account.

"); - + // Re-check the password hashing cost, if necessary do_password_hash_code_update(); } @@ -191,11 +191,11 @@ register_module([ */ function do_password_hash_code_update() { global $settings, $paths; - + // There's no point if we're using Argon2i, as it doesn't take a cost if(defined("PASSWORD_ARGON2I") && hash_password_properties()["algorithm"] == PASSWORD_ARGON2I) return; - + // Skip rechecking if the automatic check has been disabled if($settings->password_cost_time_interval == -1) return; @@ -203,9 +203,9 @@ function do_password_hash_code_update() { if(isset($settings->password_cost_time_lastcheck) && time() - $settings->password_cost_time_lastcheck < $settings->password_cost_time_interval) return; - + $new_cost = hash_password_compute_cost(); - + // Save the new cost, but only if it's higher than the old one if($new_cost > $settings->password_cost) $settings->password_cost = $new_cost; @@ -221,7 +221,7 @@ function do_password_hash_code_update() { */ function hash_password_properties() { global $settings; - + $result = [ "algorithm" => constant($settings->password_algorithm), "options" => [ "cost" => $settings->password_cost ] @@ -283,9 +283,9 @@ function hash_password_compute_cost($verbose = false) { if($props["algorithm"] == PASSWORD_ARGON2I) return null; $props["options"]["cost"] = 10; - + $target_cost_time = $settings->password_cost_time / 1000; // The setting is in ms - + do { $props["options"]["cost"]++; $start_i = microtime(true); @@ -297,6 +297,6 @@ function hash_password_compute_cost($verbose = false) { // time in total (in case the specified algorithm doesn't take a // cost parameter) } while($end_i - $start_i < $target_cost_time); - + return $props["options"]["cost"]; }