From 77998a963e57c1a6557f448f7fd1a6376094e858 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Sun, 13 Sep 2026 11:42:28 +0100 Subject: [PATCH 1/2] Fix relative Location header when Micropub creates an article EntryHandler used Article::link, which is deliberately a site-relative path elsewhere in the app, directly as the Micropub response's Location URL. Every other post type it returns (notes, bookmarks, places) already prepends the site URL, so articles were the only case where clients received a relative Location - iA Writer appears to treat that as a local file path and fails to open it after posting. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_017USyUg8PwuoDcHP8pv5xjy --- app/Services/Micropub/Handlers/EntryHandler.php | 2 +- tests/Feature/MicropubControllerTest.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Services/Micropub/Handlers/EntryHandler.php b/app/Services/Micropub/Handlers/EntryHandler.php index 48bbb550..a19f4d2b 100644 --- a/app/Services/Micropub/Handlers/EntryHandler.php +++ b/app/Services/Micropub/Handlers/EntryHandler.php @@ -37,7 +37,7 @@ class EntryHandler implements MicropubHandlerInterface $location = match (true) { isset($dataArray['like-of']) => resolve(LikeService::class)->create($dataArray)->url, isset($dataArray['bookmark-of']) => resolve(BookmarkService::class)->create($dataArray)->uri, - isset($dataArray['name']) => resolve(ArticleService::class)->create($dataArray)->link, + isset($dataArray['name']) => config('app.url').resolve(ArticleService::class)->create($dataArray)->link, default => resolve(NoteService::class)->create($dataArray)->uri, }; diff --git a/tests/Feature/MicropubControllerTest.php b/tests/Feature/MicropubControllerTest.php index efcfb6ce..e1795561 100644 --- a/tests/Feature/MicropubControllerTest.php +++ b/tests/Feature/MicropubControllerTest.php @@ -871,6 +871,8 @@ class MicropubControllerTest extends TestCase 'main' => $content, 'published' => true, ]); + $response->assertHeader('Location'); + $this->assertStringStartsWith(config('app.url').'/blog/', $response->headers->get('Location')); } #[Test] From 4aa93d63bbee4cab51ae4bd2bbe5f4448ee4bc77 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Sun, 13 Sep 2026 12:12:36 +0100 Subject: [PATCH 2/2] Add Article::uri accessor for the absolute post URL Follow the uri/link convention already used by Note, Bookmark, and Place, rather than concatenating config('app.url') inline where the absolute URL is needed. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_017USyUg8PwuoDcHP8pv5xjy --- app/Models/Article.php | 7 +++++++ app/Services/Micropub/Handlers/EntryHandler.php | 2 +- tests/Unit/ArticlesTest.php | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/Models/Article.php b/app/Models/Article.php index ab0602d1..9ac2335d 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -93,6 +93,13 @@ class Article extends Model ); } + protected function uri(): Attribute + { + return Attribute::get( + get: fn () => config('app.url').$this->link, + ); + } + /** * Scope a query to only include articles from a particular year/month. */ diff --git a/app/Services/Micropub/Handlers/EntryHandler.php b/app/Services/Micropub/Handlers/EntryHandler.php index a19f4d2b..d79a0418 100644 --- a/app/Services/Micropub/Handlers/EntryHandler.php +++ b/app/Services/Micropub/Handlers/EntryHandler.php @@ -37,7 +37,7 @@ class EntryHandler implements MicropubHandlerInterface $location = match (true) { isset($dataArray['like-of']) => resolve(LikeService::class)->create($dataArray)->url, isset($dataArray['bookmark-of']) => resolve(BookmarkService::class)->create($dataArray)->uri, - isset($dataArray['name']) => config('app.url').resolve(ArticleService::class)->create($dataArray)->link, + isset($dataArray['name']) => resolve(ArticleService::class)->create($dataArray)->uri, default => resolve(NoteService::class)->create($dataArray)->uri, }; diff --git a/tests/Unit/ArticlesTest.php b/tests/Unit/ArticlesTest.php index fda1abf4..0de3277d 100644 --- a/tests/Unit/ArticlesTest.php +++ b/tests/Unit/ArticlesTest.php @@ -63,6 +63,17 @@ class ArticlesTest extends TestCase ); } + #[Test] + public function uri_is_the_absolute_form_of_the_link(): void + { + $article = Article::create([ + 'title' => 'Test', + 'main' => 'Test', + ]); + + $this->assertEquals(config('app.url').$article->link, $article->uri); + } + #[Test] public function date_scope_returns_expected_articles(): void {