commit 055cea436cbff439fd87364a904f8136b1553810
parent 49d2581a9896fbcb60e435beb236846858a6d66c
Author: JayVii <jayvii[AT]posteo[DOT]de>
Date: Sat, 26 Oct 2024 12:29:26 +0200
fix: use (session) cookies for login
Diffstat:
10 files changed, 133 insertions(+), 165 deletions(-)
diff --git a/config/i18n.php b/config/i18n.php
@@ -20,6 +20,10 @@ if ($lang == "en") {
$GLOBALS["i18n_logout"] = "Logout";
$GLOBALS["i18n_categories"] = "Categories";
$GLOBALS["i18n_delete"] = "Delete";
+ $GLOBALS["i18n_cookie"] = "Keep me logged in! (this will set a cookie)";
+ $GLOBALS["i18n_cookie_session"] = "No, only temporarily";
+ $GLOBALS["i18n_cookie_long"] = "Yes, keep me logged in for 30 days";
+
}
diff --git a/index.php b/index.php
@@ -20,17 +20,30 @@
$filename = validate_input_string(gather_post("filename"));
$filepath_t1 = gather_post("filepath_t1");
$content = gather_post("content");
- $GLOBALS["user"] = validate_input_string(gather_post("user"));
+ $user = validate_input_string(gather_post("user"));
$pass = gather_post("pass");
- $GLOBALS["token"] = gather_post("token");
+ $token = ""; // initilise empty
+ $cookie = (int)validate_input_string(gather_post("cookie")); // cast to int
/* if password is given, but token is not, create the token! */
- if ($GLOBALS["token"] == "") {
- $GLOBALS["token"] = create_password_hash($pass);
+ $token = "";
+ if (!empty($pass)) {
+ $token = create_password_hash($pass);
+ }
+
+ /* read information from cookie */
+ if (array_key_exists("session", $_COOKIE)) {
+ $user = explode("|", $_COOKIE["session"])[0];
+ $token = explode("|", $_COOKIE["session"])[1];
+ }
+
+ /* if no action is given, set it to "list" initially */
+ if (empty($action)) {
+ $action = "list";
}
/* Check authentification of user */
- $auth = auth_user($GLOBALS["user"], $token);
+ $auth = auth_user($user, $token, $cookie);
if ($auth !== true) {
$action = "login";
}
@@ -39,13 +52,56 @@
if (
(count(preg_grep("/\.txt$/", array($filename), PREG_GREP_INVERT)) > 0)
&&
- ($filename != "")
+ (!empty($filename))
){
$filename = $filename . ".txt";
}
?>
+<?php
+
+ /* Actions Block 1: Actions that do not print */
+
+ /* Logout action */
+ if ($action == "logout") {
+ destroy_session();
+ /* set action to "login", so we return to the login screen again */
+ $action = "login";
+ }
+
+ /* Edit action */
+ if ($action == "edit") {
+ /* if no filename is given, try to come up with one ourselves */
+ if (empty($filename)) {
+ $filename = generate_filename($content);
+ }
+ /* edit note */
+ edit_note(
+ $user,
+ $category,
+ $filename,
+ $filepath_t1,
+ $content
+ );
+ /* set action to "show", so the new file will be shown afterwards */
+ $action = "show";
+ }
+
+ /* Deletion action */
+ if ($action == "delete") {
+ delete_note(
+ $user,
+ $category,
+ $filename
+ );
+ /* set action to "list", so we return to the main view again */
+ $action = "list";
+ $category = "";
+ }
+
+?>
+
<!DOCTYPE html>
<html>
@@ -83,49 +139,25 @@
?>
<?php
+
+ /* Actions Block 2: Actions that print */
+
/* Login action */
if ($action == "login") {
show_login_form("list");
die(); // ensure the process stops after this
}
- /* Deletion action */
- if ($action == "delete") {
- delete_note(
- $category,
- $filename
- );
- /* set action to "list", so we return to the main view again */
- $action = "list";
- $category = "";
- }
-
/* Listing action */
if ($action == "list") {
- category_menu();
- list_notes($category);
- }
-
- /* Edit action */
- if ($action == "edit") {
- /* if no filename is given, try to come up with one ourselves */
- if ($filename == "") {
- $filename = generate_filename($content);
- }
- /* edit note */
- edit_note(
- $category,
- $filename,
- $filepath_t1,
- $content
- );
- /* set action to "show", so the new file will be shown afterwards */
- $action = "show";
+ category_menu($user);
+ list_notes($user, $category);
}
/* Show action */
if ($action == "show") {
show_note(
+ $user,
$category,
$filename
);
diff --git a/lib/delete.php b/lib/delete.php
@@ -1,12 +1,13 @@
<?php
function delete_note(
+ string $user,
string $category,
string $filename,
) {
/* Create full file path name */
- $dirpath = "./data/" . $GLOBALS["user"] . "/" . $category;
+ $dirpath = "./data/" . $user . "/" . $category;
$filepath = $dirpath . "/" . $filename;
/* delete note */
diff --git a/lib/edit.php b/lib/edit.php
@@ -1,6 +1,7 @@
<?php
function edit_note(
+ string $user,
string $category,
string $filename,
string $filepath_t1,
@@ -9,7 +10,7 @@ function edit_note(
/* Write note as if it was completely new */
$written = write_note(
- $GLOBALS["user"],
+ $user,
$category,
$filename,
$content
@@ -27,7 +28,7 @@ function edit_note(
* delete the old one and return immediately */
$deletion = false;
if ($filepath_t1 != $filepath_t0) {
- return delete_note($category, basename($filepath_t1));
+ return delete_note($user, $category, basename($filepath_t1));
}
/* if all went fine, return "true" */
diff --git a/lib/helpers.php b/lib/helpers.php
@@ -42,7 +42,7 @@ function link_in_first_line(string $filepath) {
);
/* return link or false, if none was found */
- if ($file_link != "") {
+ if (!empty($file_link)) {
return $file_link;
} else {
return false;
@@ -50,17 +50,20 @@ function link_in_first_line(string $filepath) {
}
-function gather_notes(string $category = "") {
+function gather_notes(
+ string $user,
+ string $category = ""
+) {
/* initilise files array */
$filenames = array();
/* Create full path name */
- $dirpath = "./data/" . $GLOBALS["user"];
+ $dirpath = "./data/" . $user;
/* if no category is given, search in all categories
* if a category is given, only search in this one */
- if ($category == "") {
+ if (empty($category)) {
/* list all available categories */
$categories_path = glob($dirpath . "/*");
@@ -137,14 +140,14 @@ function generate_filename(string $content) {
'\1',
explode(PHP_EOL, $content)[0]
);
- if ($file_link != "") {
+ if (!empty($file_link)) {
$filename = page_title($file_link);
}
/* if filename is still unset after this
* (file did not contain link OR fetching page title failed)
* we use the sha256sum of the content as fallback name */
- if ($filename == "") {
+ if (empty($filename)) {
$filename = hash("sha256", $content, false);
}
diff --git a/lib/list.php b/lib/list.php
@@ -1,11 +1,12 @@
<?php
function list_notes(
+ string $user,
string $category = ""
) {
/* gather note paths, based on given category */
- $filenames = gather_notes($category);
+ $filenames = gather_notes($user, $category);
/* Sort filenames by edit timestamp */
usort($filenames, "sort_by_time");
@@ -44,18 +45,6 @@ function list_notes(
<!-- category button -->
<form action="/" target="_self" method="post" class="inline">
<input
- id="user"
- name="user"
- type="hidden"
- value="<?php echo $GLOBALS["user"]; ?>"
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value="<?php echo $GLOBALS["token"]; ?>"
- >
- <input
id="category"
name="category"
type="hidden"
@@ -80,18 +69,6 @@ function list_notes(
<!-- edit button -->
<form action="/" method="post" class="inline">
<input
- id="user"
- name="user"
- type="hidden"
- value="<?php echo $GLOBALS["user"]; ?>"
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value="<?php echo $GLOBALS["token"]; ?>"
- >
- <input
id="category"
name="category"
type="hidden"
diff --git a/lib/login.php b/lib/login.php
@@ -15,6 +15,15 @@ function show_login_form(string $target) {
type="hidden"
value="<?php echo $target; ?>"
>
+ <label for="cookie"><?php echo $GLOBALS["i18n_cookie"]; ?></label>
+ <select id="cookie" name="cookie">
+ <option value="0">
+ <?php echo $GLOBALS["i18n_cookie_session"]; ?>
+ </option>
+ <option value="30">
+ <?php echo $GLOBALS["i18n_cookie_long"]; ?>
+ </option>
+ </select>
<input type="submit" value="<?php echo $GLOBALS["i18n_login"]; ?>">
</form>
diff --git a/lib/menus.php b/lib/menus.php
@@ -10,18 +10,6 @@ function top_navigation() {
<!-- All Notes: List-Action -->
<form action="/" method="post" class="inline">
<input
- id="user"
- name="user"
- type="hidden"
- value="<?php echo $GLOBALS["user"]; ?>"
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value="<?php echo $GLOBALS["token"]; ?>"
- >
- <input
id="category"
name="category"
type="hidden"
@@ -43,18 +31,6 @@ function top_navigation() {
<!-- New Note: Edit-Action -->
<form action="/" method="post" class="inline">
<input
- id="user"
- name="user"
- type="hidden"
- value="<?php echo $GLOBALS["user"]; ?>"
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value="<?php echo $GLOBALS["token"]; ?>"
- >
- <input
id="category"
name="category"
type="hidden"
@@ -82,28 +58,10 @@ function top_navigation() {
<!-- Logout-Action -->
<form action="/" method="post" class="inline">
<input
- id="user"
- name="user"
- type="hidden"
- value=""
- >
- <input
- id="pass"
- name="pass"
- type="hidden"
- value=""
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value=""
- >
- <input
id="action"
name="action"
type="hidden"
- value="list"
+ value="logout"
>
<input
class="likenavitem"
@@ -122,7 +80,7 @@ function top_navigation() {
<?php
-function category_menu() {
+function category_menu(string $user) {
?>
@@ -132,18 +90,6 @@ function category_menu() {
<div class="inline">
<form action="/" target="_self" method="post" class="inline">
<input
- id="user"
- name="user"
- type="hidden"
- value="<?php echo $GLOBALS["user"]; ?>"
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value="<?php echo $GLOBALS["token"]; ?>"
- >
- <input
id="action"
name="action"
type="hidden"
@@ -157,7 +103,7 @@ function category_menu() {
<?php
/* Fetch all categories of the user */
- $categories_path = glob("./data/" . $GLOBALS["user"] . "/*");
+ $categories_path = glob("./data/" . $user . "/*");
foreach ($categories_path as $category_path) {
if (count(glob($category_path . "/" . "*.txt")) > 0) {
@@ -165,18 +111,6 @@ function category_menu() {
<form action="/" target="_self" method="post" class="inline">
<input
- id="user"
- name="user"
- type="hidden"
- value="<?php echo $GLOBALS["user"]; ?>"
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value="<?php echo $GLOBALS["token"]; ?>"
- >
- <input
id="category"
name="category"
type="hidden"
diff --git a/lib/show.php b/lib/show.php
@@ -1,12 +1,13 @@
<?php
function show_note(
+ string $user,
string $category,
string $filename
) {
/* Read Note: if it does not exist yet, use empty string */
- $content = read_note($GLOBALS["user"], $category, $filename);
+ $content = read_note($user, $category, $filename);
?>
@@ -40,18 +41,6 @@ function show_note(
type="hidden"
value="edit"
>
- <input
- id="user"
- name="user"
- type="hidden"
- value="<?php echo $GLOBALS["user"]; ?>"
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value="<?php echo $GLOBALS["token"]; ?>"
- >
<input type="submit" value="<?php echo $GLOBALS["i18n_save"]; ?>">
</form>
@@ -75,18 +64,6 @@ function show_note(
value="delete"
>
<input
- id="user"
- name="user"
- type="hidden"
- value="<?php echo $GLOBALS["user"]; ?>"
- >
- <input
- id="token"
- name="token"
- type="hidden"
- value="<?php echo $GLOBALS["token"]; ?>"
- >
- <input
class="danger"
type="button"
value="<?php echo $GLOBALS["i18n_delete"]; ?>"
diff --git a/lib/users.php b/lib/users.php
@@ -1,5 +1,18 @@
<?php
+function destroy_session(
+) {
+ header(
+ "Set-Cookie: " .
+ "session=; " .
+ "Max-Age=" . "-1; " .
+ "Domain=" . $_SERVER["SERVER_NAME"] . "; " .
+ "SameSite=Strict;"
+ );
+ unset($_COOKIE["session"]);
+ return true;
+}
+
function create_password_hash(
string $pass
) {
@@ -18,9 +31,14 @@ function create_password_hash(
function auth_user(
string $user,
- string $token
+ string $token,
+ int $cookie_time
) {
+ if (empty($user) || empty($token)) {
+ return false;
+ }
+
/* read token file of user */
$tokens_storage = file(
"./data/" . $user . "/.tokens",
@@ -38,6 +56,18 @@ function auth_user(
/* If matches between given hash and tokens were found, return "true" */
if (count($matches) > 0 && $matches !== false) {
+ /* set longtime or session cookie, according to preferences */
+ $cookie_content = "Set-Cookie: " .
+ "session=" . $user . "|" . $token . "; " .
+ "Domain=" . $_SERVER["SERVER_NAME"] . "; " .
+ "SameSite=Strict;";
+ if ($cookie_time > 0) {
+ $cookie_content = $cookie_content .
+ "Max-Age=" . (60 * 60 * 24 * $cookie_time) . "; ";
+ }
+ header($cookie_content);
+
+ /* return success state */
return true;
} else {
return false;