diff --git a/CHANGELOG.md b/CHANGELOG.md index 24e671828..be2af3864 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ The format is based on Keep a Changelog. ### Added - Added `Response::back()` and the `back()` helper, which redirect to the referrer and fall back to `base_url()` when the request has none, or when the referrer is not on the application origin (same scheme, host and port), which is compared with `base_url()`: behind a proxy that terminates TLS, or where the `Host` header is not pinned, set `app.base_url`. They take the old input to keep for the next request, read with `old()` as after `redirectWith()`, and an optional status code (`back($data, $code)`) (#540) +### Changed +- The `DemoWeb` and `Toolkit` module templates redirect back with `back()` instead of `redirect(get_referrer() ?? base_url())` and `redirectWith(get_referrer() ?? base_url(), $data)`, so generated code gets the same-origin check. Modules generated before keep their code (#541) + ## [3.1.0] - 2026-10-24 ### Added diff --git a/src/Module/Templates/DemoWeb/src/Controllers/CommentController.php.tpl b/src/Module/Templates/DemoWeb/src/Controllers/CommentController.php.tpl index e6705fa59..192edcc75 100644 --- a/src/Module/Templates/DemoWeb/src/Controllers/CommentController.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Controllers/CommentController.php.tpl @@ -37,7 +37,7 @@ class CommentController extends BaseController $this->commentService->addComment($commentDto); session()->setFlash('success', t('common.comment_added')); - return redirect(get_referrer() ?? base_url()); + return back(); } /** @@ -48,7 +48,7 @@ class CommentController extends BaseController $this->commentService->deleteComment($uuid); session()->setFlash('success', t('common.comment_deleted')); - return redirect(get_referrer() ?? base_url()); + return back(); } } diff --git a/src/Module/Templates/DemoWeb/src/Middlewares/Comment.php.tpl b/src/Module/Templates/DemoWeb/src/Middlewares/Comment.php.tpl index 41df81cf6..1021a8355 100644 --- a/src/Module/Templates/DemoWeb/src/Middlewares/Comment.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Middlewares/Comment.php.tpl @@ -52,7 +52,7 @@ class Comment extends BaseMiddleware $data = $request->all(); session()->setFlash('error', $this->validator->getErrors()); - return redirectWith(get_referrer() ?? base_url(), $data); + return back($data); } } diff --git a/src/Module/Templates/DemoWeb/src/Middlewares/Editor.php.tpl b/src/Module/Templates/DemoWeb/src/Middlewares/Editor.php.tpl index 3aab61bc3..f840ce49b 100644 --- a/src/Module/Templates/DemoWeb/src/Middlewares/Editor.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Middlewares/Editor.php.tpl @@ -88,7 +88,7 @@ class Editor extends BaseMiddleware unset($data['image']); session()->setFlash('error', $this->validator->getErrors()); - return redirectWith(get_referrer() ?? base_url(), $data); + return back($data); } } diff --git a/src/Module/Templates/DemoWeb/src/Middlewares/Reset.php.tpl b/src/Module/Templates/DemoWeb/src/Middlewares/Reset.php.tpl index e943c5004..08eabd617 100644 --- a/src/Module/Templates/DemoWeb/src/Middlewares/Reset.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Middlewares/Reset.php.tpl @@ -73,7 +73,7 @@ class Reset extends BaseMiddleware } session()->setFlash('error', $message); - return redirect(get_referrer() ?? base_url()); + return back(); } } diff --git a/src/Module/Templates/Toolkit/src/Controllers/DatabaseController.php.tpl b/src/Module/Templates/Toolkit/src/Controllers/DatabaseController.php.tpl index 3ca400026..002e1bfe2 100644 --- a/src/Module/Templates/Toolkit/src/Controllers/DatabaseController.php.tpl +++ b/src/Module/Templates/Toolkit/src/Controllers/DatabaseController.php.tpl @@ -75,7 +75,7 @@ class DatabaseController extends BaseController $this->databaseService->createTableRow($tableName, $newData); - return redirect(get_referrer() ?? base_url()); + return back(); } public function update(Request $request): Response diff --git a/src/Module/Templates/Toolkit/src/Middlewares/CreateTable.php.tpl b/src/Module/Templates/Toolkit/src/Middlewares/CreateTable.php.tpl index ff7e06362..5d3d3af8d 100644 --- a/src/Module/Templates/Toolkit/src/Middlewares/CreateTable.php.tpl +++ b/src/Module/Templates/Toolkit/src/Middlewares/CreateTable.php.tpl @@ -58,7 +58,7 @@ class CreateTable extends BaseMiddleware protected function respondWithError(Request $request, $message): Response { session()->setFlash('error', $message); - return redirect(get_referrer() ?? base_url()); + return back(); } /** diff --git a/tests/Unit/Module/Templates/RedirectTemplatesTest.php b/tests/Unit/Module/Templates/RedirectTemplatesTest.php new file mode 100644 index 000000000..62053abd3 --- /dev/null +++ b/tests/Unit/Module/Templates/RedirectTemplatesTest.php @@ -0,0 +1,73 @@ +templateFiles($template); + + $this->assertNotEmpty($files); + + foreach ($files as $file) { + $this->assertDoesNotMatchRegularExpression( + '/get_referrer\(\)\s*\?\?\s*base_url\(\)/', + (string) file_get_contents($file), + $file + ); + } + } + + /** + * @dataProvider redirectTemplateProvider + */ + public function testTemplatesGoBackWithTheBackRedirect(string $template): void + { + $backRedirects = 0; + + foreach ($this->templateFiles($template) as $file) { + $backRedirects += preg_match_all('/return back\(/', (string) file_get_contents($file)); + } + + $this->assertGreaterThan(0, $backRedirects); + } + + /** + * @return array + */ + public function redirectTemplateProvider(): array + { + return [ + 'demo-web' => ['DemoWeb'], + 'toolkit' => ['Toolkit'], + ]; + } + + /** + * @return array + */ + private function templateFiles(string $template): array + { + $files = []; + + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator(dirname(__DIR__, 4) . '/src/Module/Templates/' . $template . '/src') + ); + + foreach ($iterator as $file) { + if ($file->isFile() && str_ends_with($file->getFilename(), '.php.tpl')) { + $files[] = $file->getPathname(); + } + } + + return $files; + } +}