devshort

private self-hosted shortlink service
git clone https://git.clttr.info/devshort.git
Log (Feed) | Files | Refs (Tags) | README | LICENSE

commit bc1fc0487ff6381f1b2a13a4c859fdc7179674b6
parent f8049a90cfd2b088760b487e00458318412254d0
Author: René Wagner <rwa@clttr.info>
Date:   Fri,  7 Jul 2023 09:51:10 +0200

prepare for 3.3.0 release

Diffstat:
MREADME.md | 5+++--
Madmin-auth.php | 13++++++++++---
Madmin.php | 11++++++++---
Mindex.php | 4++--
Mredirect.php | 203+++++++++++++++++++++++++++++++++++++++++--------------------------------------
5 files changed, 128 insertions(+), 108 deletions(-)

diff --git a/README.md b/README.md @@ -1,8 +1,8 @@ -# devShort +# [devShort](https://sr.ht/~rwa/devshort) The devShort URL shortener is the perfect choice for web developers, admins and professionals. It is simple and privacy friendly but very powerful since it focuses on the most important things. -### Jump to our [demo](https://clttr.info)! +**Jump to our [demo](https://clttr.info)!** ## 1-2-3 Main features 1. Slim but powerful @@ -15,6 +15,7 @@ The devShort URL shortener is the perfect choice for web developers, admins and * Only the access count and date is tracked * The whole code is verifiable in minutes * Privacy and security by default + * No external dependencies ### modifications compared to original devShort * Short-URLs are case-insensitive, means "link" and "LINK" are the same redirect diff --git a/admin-auth.php b/admin-auth.php @@ -1,6 +1,6 @@ <?php -// This file is part of the devShort project under the MIT License. Visit https://github.com/flokX/devShort for more information. +// This file is part of the devShort project under the MIT License. Visit https://sr.ht/~rwa/devshort for more information. session_start(); $incorrect_password = false; @@ -51,6 +51,13 @@ if ($config_content["settings"]["custom_links"]) { $links_string = substr($links_string, 0, -1); } +$author_string = ""; +if ($config_content["settings"]["author_link"]) { + $author_string = "<a rel=\"me\" target=\"_blank\" href=\"". $config_content["settings"]["author_link"] ."\">".$config_content["settings"]["author"]."</a>"; +} else { + $author_string = $config_content["settings"]["author"]; +} + ?> <!doctype html> @@ -78,7 +85,7 @@ if ($config_content["settings"]["custom_links"]) { </ol> </nav> <h1 class="mt-5">Login</h1> - <p class="lead">Please sign in to access the admin panel. If you need help, visit <a href="https://github.com/flokX/devShort/wiki">the devShort wiki</a>.</p> + <p class="lead">Please sign in to access the admin panel.</p> <form action="admin-auth.php?login" method="POST"> <div class="alert alert-danger" role="alert" <?php if (!$incorrect_password) { echo "style=\"display: none;\""; } ?>> The given password was incorrect, please try again! @@ -95,7 +102,7 @@ if ($config_content["settings"]["custom_links"]) { <footer class="footer mt-auto py-3"> <div class="container"> <div class="d-flex justify-content-between align-items-center breadcrumb shadow-sm"> - <span class="text-dark">&copy; 2020-2023 <a href="<?php echo $config_content["settings"]["author_link"]; ?>" target="_blank"><?php echo $config_content["settings"]["author"]; ?></a> and <a href="https://sr.ht/~rwa/devshort" target="_blank">devShort</a></span> + <span class="text-dark">&copy; 2020-2023 <?php echo $author_string; ?></a> and <a href="https://sr.ht/~rwa/devshort" target="_blank">devShort</a></span> <?php if ($links_string) { echo "<span class=\"text-muted\">$links_string</span>"; } ?> </div> </div> diff --git a/admin.php b/admin.php @@ -1,7 +1,6 @@ <?php -// This file is part of the devShort project under the MIT License. Visit https://github.com/flokX/devShort for more information. -// updated by devShort see https://sr.ht/~rwa/devShort +// This file is part of the devShort project under the MIT License. Visit https://sr.ht/~rwa/devshort for more information. $config_path = implode(DIRECTORY_SEPARATOR, array(__DIR__, "data", "config.json")); $config_content = json_decode(file_get_contents($config_path), true); @@ -71,6 +70,12 @@ if ($config_content["settings"]["custom_links"]) { $links_string = substr($links_string, 0, -1); } +$author_string = ""; +if ($config_content["settings"]["author_link"]) { + $author_string = "<a rel=\"me\" target=\"_blank\" href=\"". $config_content["settings"]["author_link"] ."\">".$config_content["settings"]["author"]."</a>"; +} else { + $author_string = $config_content["settings"]["author"]; +} ?> <!doctype html> @@ -159,7 +164,7 @@ if ($config_content["settings"]["custom_links"]) { <footer class="footer mt-auto py-3"> <div class="container"> <div class="d-flex justify-content-between align-items-center breadcrumb shadow-sm"> - <span class="text-dark">&copy; 2020-2023 <a href="<?php echo $config_content["settings"]["author_link"]; ?>" target="_blank"><?php echo $config_content["settings"]["author"]; ?></a> and <a href="https://sr.ht/~rwa/devshort" target="_blank">devShort</a></span> + <span class="text-dark">&copy; 2020-2023 <?php echo $author_string; ?></a> and <a href="https://sr.ht/~rwa/devshort" target="_blank">devShort</a></span> <?php if ($links_string) { echo "<span class=\"text-muted\">$links_string</span>"; } ?> </div> </div> diff --git a/index.php b/index.php @@ -1,6 +1,6 @@ <?php -// This file is part of the devShort project under the MIT License. Visit https://github.com/flokX/devShort for more information. +// This file is part of the devShort project under the MIT License. Visit https://sr.ht/~rwa/devshort for more information. $config_path = implode(DIRECTORY_SEPARATOR, array(__DIR__, "data", "config.json")); $config_content = json_decode(file_get_contents($config_path), true); @@ -88,7 +88,7 @@ function show_random_shortlink() { <footer class="footer mt-auto py-3"> <div class="container"> <div class="d-flex justify-content-between align-items-center breadcrumb shadow-sm"> - <span class="text-dark">&copy; 2020-2023 <a href="<?php echo $config_content["settings"]["author_link"]; ?>" target="_blank"><?php echo $author_string; ?></a> and <a href="https://sr.ht/~rwa/devshort" target="_blank">devShort</a></span> + <span class="text-dark">&copy; 2020-2023 <?php echo $author_string; ?></a> and <a href="https://sr.ht/~rwa/devshort" target="_blank">devShort</a></span> <?php if ($links_string) { echo "<span class=\"text-muted\">$links_string</span>"; } ?> </div> </div> diff --git a/redirect.php b/redirect.php @@ -1,98 +1,105 @@ -<?php - -// This file is part of the devShort project under the MIT License. Visit https://github.com/flokX/devShort for more information. - -$short = strtolower(htmlspecialchars($_GET["short"])); - -$return_404 = array("assets/vendor/bootstrap/bootstrap.min.css.map", "assets/vendor/frappe-charts/frappe-charts.min.umd.js.map"); -if (in_array($short, $return_404)) { - header("HTTP/1.1 404 Not Found"); - exit; -} - -$config_path = implode(DIRECTORY_SEPARATOR, array(__DIR__, "data", "config.json")); -$config_content = json_decode(file_get_contents($config_path), true); -$stats_path = implode(DIRECTORY_SEPARATOR, array(__DIR__, "data", "stats.json")); - -// Count the access to the given $name -function count_access($name) { - global $stats_path; - - $statsfile = fopen($stats_path, 'c+'); - if (flock($statsfile, LOCK_EX)) - { - $stats_content = json_decode(fread($statsfile, filesize($stats_path)), true); - $stats_content[$name][date("Y-m-d")] += 1; - - ftruncate($statsfile, 0); - fseek($statsfile, 0); - fwrite($statsfile, json_encode($stats_content, JSON_PRETTY_PRINT)); - flock($statsfile, LOCK_UN); - } - fclose($statsfile); -} - -if (array_key_exists($short, $config_content["shortlinks"])) { - header("Location: " . $config_content["shortlinks"][$short], $http_response_code=303); - count_access($short); - exit; -} else if ($short === "") { - header("Location: index.php", $http_response_code=301); - exit; -} else { - header("HTTP/1.1 404 Not Found"); - count_access("404-request"); - - // Generate custom buttons for the footer - $links_string = ""; - if ($config_content["settings"]["custom_links"]) { - foreach ($config_content["settings"]["custom_links"] as $name => $url) { - $links_string = $links_string . "<a href=\"$url\" class=\"badge badge-secondary\">$name</a> "; - } - $links_string = substr($links_string, 0, -1); - } -} - -?> - -<!doctype html> -<html class="h-100" lang="en"> - -<head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> - <meta name="robots" content="noindex, nofollow"> - <meta name="author" content="<?php echo $config_content["settings"]["author"]; ?> and the devShort team"> - <link href="<?php echo $config_content["settings"]["favicon"]; ?>" rel="icon"> - <title>404 | <?php echo $config_content["settings"]["name"]; ?></title> - <link href="assets/vendor/bootstrap/bootstrap.min.css" rel="stylesheet"> -</head> - -<body class="d-flex flex-column h-100"> - - <main class="flex-shrink-0"> - <div class="container"> - <nav class="mt-3" aria-label="breadcrumb"> - <ol class="breadcrumb shadow-sm"> - <li class="breadcrumb-item"><a href="<?php echo $config_content["settings"]["home_link"]; ?>">Home</a></li> - <li class="breadcrumb-item"><?php echo $config_content["settings"]["name"]; ?></li> - <li class="breadcrumb-item active" aria-current="page">404</li> - </ol> - </nav> - <h1 class="mt-5">404 | Shortlink Not Found.</h1> - <p class="lead">The requested shortlink <i><?php echo $short; ?></i> was not found on this server. It was either deleted, expired, misspelled or eaten by a monster.</p> - </div> - </main> - - <footer class="footer mt-auto py-3 bg-light"> - <div class="container"> - <div class="d-flex justify-content-between align-items-center"> - <span class="text-muted">&copy; 2020 <?php $config_content["settings"]["author"]; ?> and <a href="https://github.com/flokX/devShort">devShort</a></span> - <?php if ($links_string) { echo "<span class=\"text-muted\">$links_string</span>"; } ?> - </div> - </div> - </footer> - -</body> - -</html> +<?php + +// This file is part of the devShort project under the MIT License. Visit https://sr.ht/~rwa/devshort for more information. + +$short = strtolower(htmlspecialchars($_GET["short"])); + +$return_404 = array("assets/vendor/bootstrap/bootstrap.min.css.map", "assets/vendor/frappe-charts/frappe-charts.min.umd.js.map"); +if (in_array($short, $return_404)) { + header("HTTP/1.1 404 Not Found"); + exit; +} + +$config_path = implode(DIRECTORY_SEPARATOR, array(__DIR__, "data", "config.json")); +$config_content = json_decode(file_get_contents($config_path), true); +$stats_path = implode(DIRECTORY_SEPARATOR, array(__DIR__, "data", "stats.json")); + +// Count the access to the given $name +function count_access($name) { + global $stats_path; + + $statsfile = fopen($stats_path, 'c+'); + if (flock($statsfile, LOCK_EX)) + { + $stats_content = json_decode(fread($statsfile, filesize($stats_path)), true); + $stats_content[$name][date("Y-m-d")] += 1; + + ftruncate($statsfile, 0); + fseek($statsfile, 0); + fwrite($statsfile, json_encode($stats_content, JSON_PRETTY_PRINT)); + flock($statsfile, LOCK_UN); + } + fclose($statsfile); +} + +if (array_key_exists($short, $config_content["shortlinks"])) { + header("Location: " . $config_content["shortlinks"][$short], $http_response_code=303); + count_access($short); + exit; +} else if ($short === "") { + header("Location: index.php", $http_response_code=301); + exit; +} else { + header("HTTP/1.1 404 Not Found"); + count_access("404-request"); + + // Generate custom buttons for the footer + $links_string = ""; + if ($config_content["settings"]["custom_links"]) { + foreach ($config_content["settings"]["custom_links"] as $name => $url) { + $links_string = $links_string . "<a href=\"$url\" class=\"badge badge-primary\" target=\"_blank\">$name</a> "; + } + $links_string = substr($links_string, 0, -1); + } + + $author_string = ""; + if ($config_content["settings"]["author_link"]) { + $author_string = "<a rel=\"me\" target=\"_blank\" href=\"". $config_content["settings"]["author_link"] ."\">".$config_content["settings"]["author"]."</a>"; + } else { + $author_string = $config_content["settings"]["author"]; + } +} + +?> + +<!doctype html> +<html class="h-100" lang="en"> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta name="robots" content="noindex, nofollow"> + <meta name="author" content="<?php echo $config_content["settings"]["author"]; ?> and the devShort team"> + <link href="<?php echo $config_content["settings"]["favicon"]; ?>" rel="icon"> + <title>404 | <?php echo $config_content["settings"]["name"]; ?></title> + <link href="assets/vendor/bootstrap/bootstrap.min.css" rel="stylesheet"> +</head> + +<body class="d-flex flex-column h-100"> + + <main class="flex-shrink-0"> + <div class="container"> + <nav class="mt-3" aria-label="breadcrumb"> + <ol class="breadcrumb shadow-sm"> + <li class="breadcrumb-item"><a href="<?php echo $config_content["settings"]["home_link"]; ?>">Home</a></li> + <li class="breadcrumb-item" aria-current="page"><a href="/"><?php echo $config_content["settings"]["name"]; ?></a></li> + <li class="breadcrumb-item active" aria-current="page">404</li> + </ol> + </nav> + <h1 class="mt-5">404 | Shortlink Not Found.</h1> + <p class="lead">The requested shortlink <i><?php echo $short; ?></i> was not found on this server. It was either deleted, expired, misspelled or eaten by a monster.</p> + </div> + </main> + + <footer class="footer mt-auto py-3"> + <div class="container"> + <div class="d-flex justify-content-between align-items-center breadcrumb shadow-sm"> + <span class="text-dark">&copy; 2020-2023 <?php echo $author_string; ?></a> and <a href="https://sr.ht/~rwa/devshort" target="_blank">devShort</a></span> + <?php if ($links_string) { echo "<span class=\"text-muted\">$links_string</span>"; } ?> + </div> + </div> + </footer> + +</body> + +</html>