summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Kohl <git@jonaskohl.de>2024-09-13 23:10:34 +0200
committerJonas Kohl <git@jonaskohl.de>2024-09-13 23:10:34 +0200
commit948cead0f11d33adbcf0d08773c716e1b6ebb101 (patch)
tree527067829595305d0e1bfa87557aa8f5065b7caa
parent93817fef3ead7cfd4fcde25ea2bcec02d01310a4 (diff)
More changes
-rw-r--r--src/.htaccess3
-rw-r--r--src/application/mystic/forum/orm/UserPermissions.php5
-rw-r--r--src/application/views/form_addpost.php2
-rw-r--r--src/application/views/form_delete_topic_confirm.php22
-rw-r--r--src/application/views/nav_guest.php4
-rw-r--r--src/application/views/nav_logged_in.php2
-rw-r--r--src/application/views/view_topic_start.php39
-rw-r--r--src/index.php151
8 files changed, 205 insertions, 23 deletions
diff --git a/src/.htaccess b/src/.htaccess
new file mode 100644
index 0000000..f4a5e0d
--- /dev/null
+++ b/src/.htaccess
@@ -0,0 +1,3 @@
+RewriteEngine On
+
+RewriteRule ^/?@([a-z0-9]([._](?![._])|[a-z0-9]){2,30}[a-z0-9])$ /index.php?_action=lookupuser&handle=$1 [L]
diff --git a/src/application/mystic/forum/orm/UserPermissions.php b/src/application/mystic/forum/orm/UserPermissions.php
index cd2fdf4..47af076 100644
--- a/src/application/mystic/forum/orm/UserPermissions.php
+++ b/src/application/mystic/forum/orm/UserPermissions.php
@@ -33,6 +33,7 @@ final class UserPermissions {
public const DELETE_OTHER_USER = 0x8000;
public const DELETE_OTHER_TOPIC = 0x10000;
+ public const EDIT_OTHER_TOPIC = 0x20000;
////////
@@ -40,6 +41,7 @@ final class UserPermissions {
| self::EDIT_OWN_POST
| self::DELETE_OWN_POST
| self::CREATE_OWN_TOPIC
+ | self::EDIT_OWN_TOPIC
| self::DELETE_OWN_TOPIC
| self::CREATE_OWN_ATTACHMENT
| self::EDIT_OWN_ATTACHMENT
@@ -50,7 +52,8 @@ final class UserPermissions {
public const GROUP_MOD = self::GROUP_USER
| self::EDIT_OTHER_POST
| self::DELETE_OTHER_USER
- | self::DELETE_OTHER_TOPIC;
+ | self::DELETE_OTHER_TOPIC
+ | self::EDIT_OTHER_TOPIC;
public const GROUP_ADMIN = self::GROUP_MOD
| self::CREATE_OTHER_USER
diff --git a/src/application/views/form_addpost.php b/src/application/views/form_addpost.php
index 88eda27..88648b4 100644
--- a/src/application/views/form_addpost.php
+++ b/src/application/views/form_addpost.php
@@ -20,7 +20,7 @@ if (($_formError = RequestUtils::getAndClearFormError()) !== null) {
<textarea class="form-control" id="i_message" name="message" required rows="12" cols="60" style="resize:vertical;max-height:499px"></textarea>
</div>
<div class="form-group">
- <label for="i_files">Attachments: <small>(max. 4 files, max. 2 MiB each)</small></label>
+ <label for="i_files">Attachments: <small>(max. <?= htmlentities(MAX_ATTACHMENT_COUNT) ?> files, max. <?= htmlentities(MAX_ATTACHMENT_SIZE >> 20) ?> MiB each)</small></label>
<input type="file" name="files[]" id="i_files" multiple accept="*/*">
</div>
<button type="submit" class="btn btn-success">Post reply</button>
diff --git a/src/application/views/form_delete_topic_confirm.php b/src/application/views/form_delete_topic_confirm.php
new file mode 100644
index 0000000..d38ffaa
--- /dev/null
+++ b/src/application/views/form_delete_topic_confirm.php
@@ -0,0 +1,22 @@
+<div class="panel panel-danger">
+ <div class="panel-heading">
+ <h3 class="panel-title">Do you want to delete this topic?</h3>
+ </div>
+ <div class="panel-body">
+ Are you sure you want to delete the topic <strong><em><?= htmlentities($topic->title) ?></em></strong> <strong>including all posts and attachments</strong>?<br>
+ </div>
+ <div class="panel-footer">
+ <div class="text-right">
+ <form action="." method="get" class="seamless-inline">
+ <input type="hidden" name="_action" value="viewtopic">
+ <input type="hidden" name="topic" value="<?= htmlentities($topic->id) ?>">
+ <button class="btn btn-default">Keep topic</button>
+ </form>
+ <form action="?_action=deletetopic" method="post" class="seamless-inline">
+ <input type="hidden" name="topic" value="<?= htmlentities($topic->id) ?>">
+ <input type="hidden" name="confirm" value="<?= htmlentities(base64_encode(hash("sha256", "confirm" . $topic->id, true))); ?>">
+ <button class="btn btn-danger">Delete topic &amp; posts</button>
+ </form>
+ </div>
+ </div>
+</div>
diff --git a/src/application/views/nav_guest.php b/src/application/views/nav_guest.php
index 433c487..f897763 100644
--- a/src/application/views/nav_guest.php
+++ b/src/application/views/nav_guest.php
@@ -1,6 +1,6 @@
<ul class="nav navbar-nav navbar-right">
-<li<?= $GLOBALS["action"] === "auth" ? ' class="active"' : '' ?>><a href="?_action=auth">Log in</a></li>
+<li<?= $GLOBALS["action"] === "auth" ? ' class="active"' : '' ?>><a href="?_action=auth&amp;next=<?= htmlentities(urlencode($_SERVER["REQUEST_URI"])) ?>">Log in</a></li>
<?php if (REGISTRATION_ENABLED): ?>
-<li<?= $GLOBALS["action"] === "register" ? ' class="active"' : '' ?>><a href="?_action=register">Register</a></li>
+<li<?= $GLOBALS["action"] === "register" ? ' class="active"' : '' ?>><a href="?_action=register&amp;next=<?= htmlentities(urlencode($_SERVER["REQUEST_URI"])) ?>">Register</a></li>
<?php endif; ?>
</ul> \ No newline at end of file
diff --git a/src/application/views/nav_logged_in.php b/src/application/views/nav_logged_in.php
index fd46d6e..f899ad8 100644
--- a/src/application/views/nav_logged_in.php
+++ b/src/application/views/nav_logged_in.php
@@ -10,5 +10,5 @@ use mystic\forum\orm\User;
<?php endif; ?>
</p></li>
<li><a href="?_action=viewuser&amp;user=<?= htmlentities(urlencode($user->id)) ?>"><span class="glyphicon glyphicon-user" aria-hidden="true"><span class="sr-only">View profile</span></a></li>
-<li><a href="?_action=logout"><span class="glyphicon glyphicon-log-out" aria-hidden="true"><span class="sr-only">Log out</span></a></li>
+<li><a href="?_action=logout&amp;next=<?= htmlentities(urlencode($_SERVER["REQUEST_URI"])) ?>"><span class="glyphicon glyphicon-log-out" aria-hidden="true"><span class="sr-only">Log out</span></a></li>
</ul>
diff --git a/src/application/views/view_topic_start.php b/src/application/views/view_topic_start.php
index 84a29de..4006982 100644
--- a/src/application/views/view_topic_start.php
+++ b/src/application/views/view_topic_start.php
@@ -3,13 +3,19 @@ use mystic\forum\orm\UserPermissions;
$canReply = $GLOBALS["currentUser"]?->hasPermission(UserPermissions::CREATE_OWN_POST) ?? false;
+$canEdit = ($GLOBALS["currentUser"]?->id === $topicAuthor->id && $topicAuthor->hasPermission(UserPermissions::EDIT_OWN_TOPIC))
+ || ($GLOBALS["currentUser"]?->hasPermission(UserPermissions::EDIT_OTHER_TOPIC));
+
$canDelete = ($GLOBALS["currentUser"]?->id === $topicAuthor->id && $topicAuthor->hasPermission(UserPermissions::DELETE_OWN_TOPIC))
|| ($GLOBALS["currentUser"]?->hasPermission(UserPermissions::DELETE_OTHER_TOPIC));
?>
-<div class="page-header margin-top-0">
- <div role="heading" class="h1 margin-top-0">
+<div class="page-header margin-top-0 clearfix">
+ <div role="heading" class="h1 margin-top-0" id="displayHeading">
<?= htmlentities($topic->title) ?>
<div class="pull-right">
+ <?php if ($canEdit): ?>
+ <button id="btn-edit-title" class="btn btn-default js-only"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit title</button>
+ <?php endif; ?>
<?php if ($canReply): ?>
<button id="btn-reply" class="btn btn-default js-only"><span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span> Reply</button>
<?php endif; ?>
@@ -21,6 +27,20 @@ $canDelete = ($GLOBALS["currentUser"]?->id === $topicAuthor->id && $topicAuthor-
<?php endif; ?>
</div>
</div>
+ <?php if ($canEdit): ?>
+ <form action="?_action=updatetopic" method="post" id="editHeading" style="display: none;" class="form-inline seamless-inline" style="display: block">
+ <input type="hidden" name="topic" value="<?= htmlentities(urlencode($topic->id)) ?>">
+ <div class="row">
+ <div class="col-md-8">
+ <input type="text" class="form-control" name="title" id="i_edit_title" value="<?= htmlentities($topic->title) ?>" style="box-sizing: border-box; width: 100%">
+ </div>
+ <div class="col-md-4 text-right">
+ <button type="button" id="topicTitleEditCancel" class="btn btn-default"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Cancel</button>
+ <button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Save changes</button>
+ </div>
+ </div>
+ </form>
+ <?php endif; ?>
</div>
<p>
Started by
@@ -31,8 +51,21 @@ Started by
<?php endif; ?>
on <span class="_time"><?= htmlentities($topic->creationDate->format("c")) ?></span>
</p>
-<?php if ($canReply): ?>
<script>
+<?php if ($canEdit): ?>
+$(function() {
+ $("#btn-edit-title").click(function() {
+ $("#displayHeading").hide();
+ $("#editHeading").show();
+ $("#i_edit_title").focus();
+ });
+ $("#topicTitleEditCancel").click(function() {
+ $("#displayHeading").show();
+ $("#editHeading").hide();
+ });
+});
+<?php endif; ?>
+<?php if ($canReply): ?>
$(function() {
function focusReplyBox() {
var msgInput = $("#i_message");
diff --git a/src/index.php b/src/index.php
index 1cc0d01..6258131 100644
--- a/src/index.php
+++ b/src/index.php
@@ -148,7 +148,7 @@ $GLOBALS["currentUser"] = &$currentUser;
if ($_action === "auth") {
if ($currentUser) {
- header("Location: .");
+ header("Location: " . $_GET["next"] ?? ".");
exit;
}
@@ -167,7 +167,7 @@ if ($_action === "auth") {
}
RequestUtils::setAuthorizedUser($user);
- header("Location: .");
+ header("Location: " . $_GET["next"] ?? ".");
} else {
_view("template_start", ["_title" => "Forum"]);
_view("template_navigation_start");
@@ -178,7 +178,7 @@ if ($_action === "auth") {
}
} elseif ($_action === "register") {
if ($currentUser) {
- header("Location: .");
+ header("Location: " . $_GET["next"] ?? ".");
exit;
}
@@ -259,7 +259,7 @@ if ($_action === "auth") {
}
} elseif ($_action === "logout") {
RequestUtils::unsetAuthorizedUser();
- header("Location: .");
+ header("Location: " . $_GET["next"] ?? ".");
} elseif ($_action === "viewtopic") {
$topicId = $_GET["topic"] ?? throw new Exception("Missing topic id");
$topic = new Topic();
@@ -343,8 +343,8 @@ if ($_action === "auth") {
/** @var Post $post */
foreach ($posts as $post) {
- /** @var ?User $postAuthor */
- $postAuthor = null;
+ /** @var ?User $topicAuthor */
+ $topicAuthor = null;
if ($post->authorId !== null && !isset($userCache[$post->authorId])) {
$usr = new User();
$usr->id = $post->authorId;
@@ -352,13 +352,13 @@ if ($_action === "auth") {
$userCache[$post->authorId] = &$usr;
}
if (isset($userCache[$post->authorId]))
- $postAuthor = &$userCache[$post->authorId];
+ $topicAuthor = &$userCache[$post->authorId];
$attachments = $db->fetchCustom(Attachment::class, 'WHERE post_id = $1', [ $post->id ]);
_view("view_post", [
"post" => $post,
- "postAuthor" => $postAuthor,
+ "postAuthor" => $topicAuthor,
"attachments" => $attachments,
]);
}
@@ -418,6 +418,20 @@ if ($_action === "auth") {
_view("form_newtopic");
_view("template_end");
}
+} elseif ($_action === "lookupuser") {
+ RequestUtils::ensureRequestMethod("GET");
+ $userHandle = $_GET["handle"] ?? throw new Exception("Missing handle");
+
+ $user = new User();
+ $user->name = $userHandle;
+
+ if (!$db->fetchWhere($user, "name")) {
+ http_response_code(404);
+ Messaging::error("No user with name @$userHandle");
+ exit;
+ }
+
+ header("Location: ./?_action=viewuser&user=" . urlencode($user->id));
} elseif ($_action === "viewuser") {
$userId = $_GET["user"] ?? throw new Exception("Missing user id");
$user = new User();
@@ -663,16 +677,16 @@ if ($_action === "auth") {
exit;
}
- $postAuthor = new User();
- $postAuthor->id = $post->authorId;
+ $topicAuthor = new User();
+ $topicAuthor->id = $post->authorId;
- if (!$db->fetch($postAuthor))
- $postAuthor = null;
+ if (!$db->fetch($topicAuthor))
+ $topicAuthor = null;
- $canDelete = ($currentUser->id === $postAuthor?->id && $postAuthor?->hasPermission(UserPermissions::DELETE_OWN_POST))
+ $canEdit = ($currentUser->id === $topicAuthor?->id && $topicAuthor?->hasPermission(UserPermissions::DELETE_OWN_POST))
|| ($currentUser->hasPermission(UserPermissions::DELETE_OTHER_POST));
- if (!$canDelete) {
+ if (!$canEdit) {
http_response_code(403);
Messaging::error("You don't have permission to delete this post");
exit;
@@ -714,11 +728,118 @@ if ($_action === "auth") {
_view("template_navigation_end");
_view("form_delete_post_confirm", [
"post" => $post,
- "postAuthor" => $postAuthor,
+ "postAuthor" => $topicAuthor,
"attachments" => $attachments,
]);
_view("template_end");
}
+} elseif ($_action === "deletetopic") {
+ RequestUtils::ensureRequestMethod("POST");
+
+ if (!$currentUser) {
+ http_response_code(403);
+ Messaging::error("You need to be logged in to delete topics!");
+ exit;
+ }
+
+ $topicId = RequestUtils::getRequiredField("topic");
+
+ $topic = new Topic();
+ $topic->id = $topicId;
+
+ if (!$db->fetch($topic)) {
+ http_response_code(404);
+ Messaging::error("No topic exists with this id");
+ exit;
+ }
+
+ $topicAuthor = new User();
+ $topicAuthor->id = $topic->createdBy;
+
+ if (!$db->fetch($topicAuthor))
+ $topicAuthor = null;
+
+ $canEdit = ($currentUser->id === $topicAuthor?->id && $topicAuthor?->hasPermission(UserPermissions::DELETE_OWN_TOPIC))
+ || ($currentUser->hasPermission(UserPermissions::DELETE_OTHER_TOPIC));
+
+ if (!$canEdit) {
+ http_response_code(403);
+ Messaging::error("You don't have permission to delete this topic");
+ exit;
+ }
+
+ $confirm = $_POST["confirm"] ?? null;
+ if ($confirm !== null) {
+ $expectedConfirm = base64_encode(hash("sha256", "confirm" . $topic->id, true));
+ if ($confirm !== $expectedConfirm) {
+ http_response_code(400);
+ Messaging::error("Invalid confirmation");
+ exit;
+ }
+
+ if (!$db->delete($topic)) {
+ http_response_code(500);
+ Messaging::error("Failed to delete topic");
+ exit;
+ }
+
+ header("Location: .");
+ } else {
+ _view("template_start", ["_title" => "Forum"]);
+ _view("template_navigation_start");
+ _view("template_navigation", ["user" => RequestUtils::getAuthorizedUser($db)]);
+ _view("template_navigation_end");
+ _view("form_delete_topic_confirm", [
+ "topic" => $topic,
+ "topicAuthor" => $topicAuthor,
+ ]);
+ _view("template_end");
+ }
+} elseif ($_action === "updatetopic") {
+ RequestUtils::ensureRequestMethod("POST");
+
+ if (!$currentUser) {
+ http_response_code(403);
+ Messaging::error("You need to be logged in to update topics!");
+ exit;
+ }
+
+ $topicId = RequestUtils::getRequiredField("topic");
+ $title = RequestUtils::getRequiredField("title");
+
+ $topic = new Topic();
+ $topic->id = $topicId;
+
+ if (!$db->fetch($topic)) {
+ http_response_code(404);
+ Messaging::error("No topic exists with this id");
+ exit;
+ }
+
+ $topicAuthor = new User();
+ $topicAuthor->id = $topic->createdBy;
+
+ if (!$db->fetch($topicAuthor))
+ $topicAuthor = null;
+
+ $canEdit = ($currentUser->id === $topicAuthor?->id && $topicAuthor?->hasPermission(UserPermissions::EDIT_OWN_TOPIC))
+ || ($currentUser->hasPermission(UserPermissions::EDIT_OTHER_TOPIC));
+
+ if (!$canEdit) {
+ http_response_code(403);
+ Messaging::error("You don't have permission to update this topic");
+ exit;
+ }
+
+ $topic->title = $title;
+
+ if (!$db->update($topic)) {
+ http_response_code(500);
+ Messaging::error("Failed to update topic");
+ exit;
+ }
+
+ header("Location: ./?_action=viewtopic&topic=" . urlencode($topicId));
} elseif ($_action === null) {
_view("template_start", ["_title" => "Forum"]);
_view("template_navigation_start");