From 518586b6ab57152ce5339a2f2bf7fc3454cd37d1 Mon Sep 17 00:00:00 2001 From: Ghostie Date: Sun, 12 Jan 2025 15:10:44 -0500 Subject: [PATCH] added note visibility --- TODO.md | 6 ++-- app/Actions/ActionsPost.php | 1 + .../Controllers/AP/APOutboxController.php | 29 ++++++++++++++++ app/Http/Controllers/PostController.php | 2 ++ app/Http/Controllers/UserActionController.php | 3 +- app/Models/Hashtag.php | 2 +- app/Models/Note.php | 33 ++++++++++++++++++- app/Types/TypeNote.php | 26 ++++++++++----- ...00_add_visibility_field_to_notes_table.php | 28 ++++++++++++++++ .../views/components/comment_block.blade.php | 3 ++ .../views/components/create_note.blade.php | 13 ++++++-- 11 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 database/migrations/2025_01_12_194500_add_visibility_field_to_notes_table.php diff --git a/TODO.md b/TODO.md index 33ef283..1a7b4ab 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,7 @@ - [-] Activitypub - [x] Accounts - - [-] Posts + - [x] Posts - [x] Local posts should be federated - [x] Local posts should be deleted - [x] Remote posts should be fetched @@ -18,10 +18,10 @@ - [x] Tags - [x] Mentions - [x] Local mentions - - [ ] Private post + - [x] Private post - [x] Pinned Posts - [x] Nodeinfo - - [ ] Notifications + - [x] Notifications - [-] Social features - [x] Profile diff --git a/app/Actions/ActionsPost.php b/app/Actions/ActionsPost.php index 0c32a14..de61426 100644 --- a/app/Actions/ActionsPost.php +++ b/app/Actions/ActionsPost.php @@ -125,6 +125,7 @@ class ActionsPost "summary" => $processed ["summary"], "content" => $processed ["content"], "attachments" => $processed ["attachments"], + "visibility" => $request ["visibility"], "inReplyTo" => $processed ["inReplyTo"] ?? null, "tags" => $processed ["tags"] ?? null, "mentions" => $processed ["mentions"] ?? null diff --git a/app/Http/Controllers/AP/APOutboxController.php b/app/Http/Controllers/AP/APOutboxController.php index 2c642ca..997a3c6 100644 --- a/app/Http/Controllers/AP/APOutboxController.php +++ b/app/Http/Controllers/AP/APOutboxController.php @@ -370,6 +370,7 @@ class APOutboxController extends Controller } } + $mentions = []; if (isset ($request ["mentions"])) { foreach ($request ["mentions"] as $mention) @@ -387,9 +388,37 @@ class APOutboxController extends Controller "note_id" => $note->id, "actor_id" => $object->id ]); + + $mentions[] = $object->actor_id; } } + if ($request ["visibility"] == "public") + { + $note->to = [ + "https://www.w3.org/ns/activitystreams#Public" + ]; + $note->cc = [ + $actor->followers + ]; + } + else if ($request ["visibility"] == "followers") + { + // TODO: Boosting should be disabled + $note->to = [ + $actor->followers + ]; + $note->cc = []; + } + else if ($request ["visibility"] == "private") + { + // TODO: Boosting should be disabled + $note->to = $mentions; + } + + $note->visibility = $request ["visibility"]; + $note->save (); + $create_activity = TypeActivity::craft_create ($actor, $note); $create_activity->to = $note->to; diff --git a/app/Http/Controllers/PostController.php b/app/Http/Controllers/PostController.php index 5750149..fe2a013 100644 --- a/app/Http/Controllers/PostController.php +++ b/app/Http/Controllers/PostController.php @@ -21,6 +21,8 @@ class PostController extends Controller if (!$actor) return redirect ()->back (); + if (!$note->can_view ()) + return redirect ()->back ()->with ("error", "You are not allowed to view this post."); return view ("posts.show", compact ("note", "actor")); } diff --git a/app/Http/Controllers/UserActionController.php b/app/Http/Controllers/UserActionController.php index 6f345b9..69e1354 100644 --- a/app/Http/Controllers/UserActionController.php +++ b/app/Http/Controllers/UserActionController.php @@ -32,7 +32,8 @@ class UserActionController extends Controller $request->validate ([ "summary" => "nullable|string", "content" => "required", - "files.*" => "max:4096" + "files.*" => "max:4096", + "visibility" => "required|in:public,private,followers", ]); $response = ActionsPost::post_new ($request); diff --git a/app/Models/Hashtag.php b/app/Models/Hashtag.php index 939a62e..e038edf 100644 --- a/app/Models/Hashtag.php +++ b/app/Models/Hashtag.php @@ -11,6 +11,6 @@ class Hashtag extends Model ]; public function get_notes () { - return $this->belongsToMany(Note::class, 'note_hashtag'); + return $this->belongsToMany(Note::class, 'note_hashtag')->orderBy('created_at', 'desc'); } } diff --git a/app/Models/Note.php b/app/Models/Note.php index e3ea891..8db1596 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -20,7 +20,8 @@ class Note extends Model "content", "tag", "to", - "cc" + "cc", + "visibility" ]; protected $casts = [ @@ -88,4 +89,34 @@ class Note extends Model { return ProfilePin::where ("actor_id", $actor->id)->where ("note_id", $this->id)->first (); } + + public function can_view (Actor $actor = null) + { + $final_actor = $actor; + $note_actor = $this->get_actor ()->first (); + if (!$final_actor && auth ()->check ()) + { + $final_actor = auth ()->user ()->actor; + } + + if ($this->visibility == "public") + { + return true; + } + else if ($this->visibility == "followers" && $final_actor) + { + return $final_actor->friends_with ($note_actor); + } + else if ($this->visibility == "private" && $final_actor) + { + if ($final_actor == $note_actor) + return true; + + $mention_exists = NoteMention::where ("note_id", $this->id)->where ("actor_id", $final_actor->id)->first (); + if ($mention_exists) + return true; + } + + return false; + } } diff --git a/app/Types/TypeNote.php b/app/Types/TypeNote.php index 1c607d7..cb89454 100644 --- a/app/Types/TypeNote.php +++ b/app/Types/TypeNote.php @@ -86,14 +86,6 @@ class TypeNote "attributedTo" => $actor->actor_id, "content" => $request ["content"] ?? null, "tag" => $request ["tag"] ?? null, - - // TODO: This should change when I implement visibilities and private notes - "to" => [ - "https://www.w3.org/ns/activitystreams#Public" - ], - "cc" => [ - $actor->followers - ] ]); $note->url = route ('posts.show', $note->id); @@ -107,6 +99,7 @@ class TypeNote if ($activity) $note->activity_id = $activity->id; + $note_actor = $actor; if ($actor) $note->actor_id = $actor->id; else @@ -122,6 +115,7 @@ class TypeNote } $note->actor_id = $actor->id; + $note_actor = $actor; } $note->note_id = $request["id"] ?? null; @@ -132,6 +126,8 @@ class TypeNote $note->content = $request["content"] ?? null; $note->tag = $request["tag"] ?? null; $note->created_at = $request["published"] ?? null; + $note->to = $request["to"] ?? null; + $note->cc = $request["cc"] ?? null; $attachments = $note->attachments ()->get (); foreach ($attachments as $attachment) @@ -238,6 +234,20 @@ class TypeNote { // TODO: Handle replies } + + $note_to = $note->to; + if (in_array ("https://www.w3.org/ns/activitystreams#Public", $note_to)) + { + $note->visibility = "public"; + } + else if (in_array ($note_actor->followers, $note_to)) + { + $note->visibility = "followers"; + } + else + { + $note->visibility = "private"; + } } public static function create_from_request ($request, Activity $activity, Actor $actor) diff --git a/database/migrations/2025_01_12_194500_add_visibility_field_to_notes_table.php b/database/migrations/2025_01_12_194500_add_visibility_field_to_notes_table.php new file mode 100644 index 0000000..f4503b9 --- /dev/null +++ b/database/migrations/2025_01_12_194500_add_visibility_field_to_notes_table.php @@ -0,0 +1,28 @@ +string ("visibility")->default ("public"); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('notes', function (Blueprint $table) { + $table->dropColumn ("visibility"); + }); + } +}; diff --git a/resources/views/components/comment_block.blade.php b/resources/views/components/comment_block.blade.php index b780cb1..85c6ff2 100644 --- a/resources/views/components/comment_block.blade.php +++ b/resources/views/components/comment_block.blade.php @@ -21,6 +21,9 @@ if ($actor->user_id) $actor_url = route ('users.show', [ 'user_name' => $actor->user->name ]); else $actor_url = route ('users.show', [ 'user_name' => $actor->local_actor_id ]); + +if (!$display_post->can_view ()) + return; @endphp diff --git a/resources/views/components/create_note.blade.php b/resources/views/components/create_note.blade.php index 27feb9a..9b6468a 100644 --- a/resources/views/components/create_note.blade.php +++ b/resources/views/components/create_note.blade.php @@ -10,9 +10,18 @@
-
- Markdown is supported +
+
+

+ Visibility: + +

+ @error ("content")
{{ $message }}