From 84320c387b81682f87c1740ec789bb3143ab16d9 Mon Sep 17 00:00:00 2001 From: Cesar Garcia Date: Tue, 28 Mar 2023 20:20:55 +0200 Subject: [PATCH 01/22] Add remember me to LoginAction (#94) --- README.md | 8 +++++++- phpstan.neon.dist | 3 --- src/Actions/LoginAction.php | 11 ++++++++++- tests/Actions/LoginTest.php | 19 +++++++++++++++++++ tests/TestCase.php | 1 + 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7caed7b..605bfb1 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,13 @@ $urlShowView = MagicLink::create($action)->url; // Sample 3; Login in other guard and redirect default $action = new LoginAction(User::first()); -$action->guard('customguard')->response(redirect('/api/dashboard')); +$action->guard('customguard'); + +$urlShowView = MagicLink::create($action)->url; + +// Sample 4; Login and remember me +$action = new LoginAction(User::first()); +$action->remember(); $urlShowView = MagicLink::create($action)->url; ``` diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ed01397..bd091d3 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -13,9 +13,6 @@ parameters: checkMissingIterableValueType: false ignoreErrors: - - - message: '#Parameter \#1 \$view of function view expects view-string|null, string given.#' - path: tests - message: '#Unsafe usage of new static\(\)#' path: src/MagicLink.php diff --git a/src/Actions/LoginAction.php b/src/Actions/LoginAction.php index 2529711..8658ee3 100644 --- a/src/Actions/LoginAction.php +++ b/src/Actions/LoginAction.php @@ -11,6 +11,8 @@ class LoginAction extends ResponseAction protected $guard; + protected bool $remember = false; + /** * Constructor to action. * @@ -25,6 +27,13 @@ public function __construct(Authenticatable $user, $httpResponse = null, ?string $this->guard = $guard; } + public function remember(bool $remember = true): self + { + $this->remember = $remember; + + return $this; + } + public function guard(string $guard): self { $this->guard = $guard; @@ -37,7 +46,7 @@ public function guard(string $guard): self */ public function run() { - Auth::guard($this->guard)->loginUsingId($this->authIdentifier); + Auth::guard($this->guard)->loginUsingId($this->authIdentifier, $this->remember); return parent::run(); } diff --git a/tests/Actions/LoginTest.php b/tests/Actions/LoginTest.php index 2df2a43..50c1c22 100644 --- a/tests/Actions/LoginTest.php +++ b/tests/Actions/LoginTest.php @@ -43,4 +43,23 @@ public function test_auth_custom() $this->assertAuthenticatedAs(new CustomAutenticable('user_1')); } + + public function test_auth_with_remember_me() + { + $action = new LoginAction(User::first()); + $action->remember(); + + $magiclink = MagicLink::create($action); + + $data = $this->get($magiclink->url) + ->assertStatus(302) + ->assertRedirect('/'); + + $cookieRememberMe = array_values(array_filter( + $data->headers->getCookies(), + fn($cookie) => str_starts_with($cookie->getName(),'remember_web_') + ))[0] ?? null; + + $this->assertNotNull($cookieRememberMe); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 95640d5..f35f6de 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -99,6 +99,7 @@ protected function setUpDatabase($app) $app['db']->connection()->getSchemaBuilder()->create('users', function (Blueprint $table) { $table->increments('id'); $table->string('email'); + $table->string('remember_token')->nullable(); }); User::create(['email' => 'test@user.com']); From c89cd3578b5190d42d33787c53e33cdcb8e4e1f6 Mon Sep 17 00:00:00 2001 From: cesargb Date: Tue, 28 Mar 2023 18:21:25 +0000 Subject: [PATCH 02/22] Commit from GitHub Actions (style-fix) --- tests/Actions/LoginTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Actions/LoginTest.php b/tests/Actions/LoginTest.php index 50c1c22..acfb3c7 100644 --- a/tests/Actions/LoginTest.php +++ b/tests/Actions/LoginTest.php @@ -57,7 +57,7 @@ public function test_auth_with_remember_me() $cookieRememberMe = array_values(array_filter( $data->headers->getCookies(), - fn($cookie) => str_starts_with($cookie->getName(),'remember_web_') + fn ($cookie) => str_starts_with($cookie->getName(), 'remember_web_') ))[0] ?? null; $this->assertNotNull($cookieRememberMe); From 8465ed3852edcde81518f5c9fe1ebcc41c49b78d Mon Sep 17 00:00:00 2001 From: Cesar Garcia Date: Sat, 15 Apr 2023 13:46:26 +0200 Subject: [PATCH 03/22] Exclude in MagicLinkMiddleware http head request (#97) * dont run middlewarein http GET request * add test to http request --- src/Middlewares/MagiclinkMiddleware.php | 4 ++ tests/HttpTest.php | 63 +++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/HttpTest.php diff --git a/src/Middlewares/MagiclinkMiddleware.php b/src/Middlewares/MagiclinkMiddleware.php index 5f91103..39863f8 100644 --- a/src/Middlewares/MagiclinkMiddleware.php +++ b/src/Middlewares/MagiclinkMiddleware.php @@ -11,6 +11,10 @@ class MagiclinkMiddleware { public function handle(Request $request, Closure $next) { + if($request->method() === 'HEAD') { + return $next($request); + } + $token = (string) $request->route('token'); $magicLink = MagicLink::getValidMagicLinkByToken($token); diff --git a/tests/HttpTest.php b/tests/HttpTest.php new file mode 100644 index 0000000..f1532e5 --- /dev/null +++ b/tests/HttpTest.php @@ -0,0 +1,63 @@ +num_visits = 4; + $magiclink->save(); + + $this->get($magiclink->url) + ->assertStatus(200) + ->assertSeeText('private content'); + + $magiclink->refresh(); + + $this->assertEquals(5, $magiclink->num_visits); + } + + public function test_http_head_request_has_not_effects() + { + $magiclink = MagicLink::create(new ResponseAction(function () { + return 'private content'; + })); + + $magiclink->num_visits = 4; + $magiclink->save(); + + $this->head($magiclink->url) + ->assertStatus(200) + ->assertDontSeeText('private content'); + + $magiclink->refresh(); + + $this->assertEquals(4, $magiclink->num_visits); + } + + public function test_http_options_request_has_not_effects() + { + $magiclink = MagicLink::create(new ResponseAction(function () { + return 'private content'; + })); + + $magiclink->num_visits = 4; + $magiclink->save(); + + $this->options($magiclink->url) + ->assertStatus(200) + ->assertDontSeeText('private content'); + + $magiclink->refresh(); + + $this->assertEquals(4, $magiclink->num_visits); + } +} From 1ff50d9179693374e48e1a794a7ac7d121afaed2 Mon Sep 17 00:00:00 2001 From: Cesar Garcia Date: Mon, 24 Apr 2023 19:18:39 +0200 Subject: [PATCH 04/22] Add custom views to required access code (#98) --- README.md | 12 +++ config/magiclink.php | 3 + src/AccessCode.php | 5 +- tests/AccessCodeTest.php | 15 ++++ .../views/access-code-custom.blade.php | 75 +++++++++++++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 tests/stubs/resources/views/access-code-custom.blade.php diff --git a/README.md b/README.md index 605bfb1..19bf77f 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,18 @@ $magiclink->protectWithAccessCode('secret'); $urlToSend = $magiclink->url; ``` +### Custom view for access code + +You can customize the view of the access code form with the config file `magiclink.php`: + +```php +'access_code' => [ + 'view' => 'magiclink::access-code', // Change with your view +], +``` + +This is the [default view](/resources/views/ask-for-access-code-form.blade.php) + ## Lifetime By default a link will be available for 72 hours after your creation. We can diff --git a/config/magiclink.php b/config/magiclink.php index 5b984e4..eeacb7d 100644 --- a/config/magiclink.php +++ b/config/magiclink.php @@ -64,4 +64,7 @@ */ 'disable_default_route' => false, + 'access_code' => [ + 'view' => 'magiclink::ask-for-access-code-form', + ] ]; diff --git a/src/AccessCode.php b/src/AccessCode.php index 3524da2..bad108b 100644 --- a/src/AccessCode.php +++ b/src/AccessCode.php @@ -74,7 +74,10 @@ private function getResponseAccessCodeFromCookie() } } - return response()->view('magiclink::ask-for-access-code-form', [], 403); + return response()->view( + config('magiclink.access-code.view', 'magiclink::ask-for-access-code-form'), + [], + 403); } return null; diff --git a/tests/AccessCodeTest.php b/tests/AccessCodeTest.php index 7559515..41b99c9 100644 --- a/tests/AccessCodeTest.php +++ b/tests/AccessCodeTest.php @@ -103,4 +103,19 @@ public function test_forbidden_if_provide_access_code_of_other_link() ->get($magiclinkOther->url) ->assertStatus(403); } + + public function test_forbidden_if_protected_with_access_code_custmo() + { + $magiclink = MagicLink::create(new ResponseAction(function () { + return 'the big secret'; + })); + + config(['magiclink.access-code.view' => 'access-code-custom']); + + $magiclink->protectWithAccessCode('1234'); + + $this->get($magiclink->url) + ->assertStatus(403) + ->assertViewIs('access-code-custom'); + } } diff --git a/tests/stubs/resources/views/access-code-custom.blade.php b/tests/stubs/resources/views/access-code-custom.blade.php new file mode 100644 index 0000000..249a931 --- /dev/null +++ b/tests/stubs/resources/views/access-code-custom.blade.php @@ -0,0 +1,75 @@ + + + + Password protected + + + + + + +
+
+
Enter access code
+ +
+ {{ csrf_field() }} + +
+ + + @if (Request::get('access-code')) +
Access code is wrong
+ @else +
And press enter
+ @endif +
+ + + +
+
+
+ + From ac8287e9c770f9335a84744b61e3e3d39bbfd898 Mon Sep 17 00:00:00 2001 From: cesargb Date: Mon, 24 Apr 2023 17:19:16 +0000 Subject: [PATCH 05/22] Commit from GitHub Actions (style-fix) --- src/AccessCode.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/AccessCode.php b/src/AccessCode.php index bad108b..1a84570 100644 --- a/src/AccessCode.php +++ b/src/AccessCode.php @@ -77,7 +77,8 @@ private function getResponseAccessCodeFromCookie() return response()->view( config('magiclink.access-code.view', 'magiclink::ask-for-access-code-form'), [], - 403); + 403 + ); } return null; From dfe12b20c4de196b42da19a5ee7501dc0cf4aba3 Mon Sep 17 00:00:00 2001 From: Peter Quentin Date: Sat, 20 May 2023 18:12:12 +0200 Subject: [PATCH 06/22] Publish migrations (#100) * Publish migrations instead of loading them * Change TestCase to load database migrations, to use newer api and move app key to xml * Update README.md with how-to publish migrations * Move back artisan migrate just in case pgsql is relying on this --- README.md | 12 +++++++++ phpunit.postgres.xml | 1 + phpunit.xml.dist | 3 +++ src/MagicLinkServiceProvider.php | 4 ++- tests/TestCase.php | 43 +++++++++++++++++--------------- 5 files changed, 42 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 19bf77f..855cd14 100644 --- a/README.md +++ b/README.md @@ -300,6 +300,7 @@ MagicLink fires two events: ## Customization +### Config To custom this package you can publish the config file: ```bash @@ -308,6 +309,17 @@ php artisan vendor:publish --provider="MagicLink\MagicLinkServiceProvider" --tag And edit the file `config/magiclink.php` + +### Migrations +To customize the migration files of this package you need to publish the migration files: + +```bash +php artisan vendor:publish --provider="MagicLink\MagicLinkServiceProvider" --tag="migrations" +``` + +You'll find the published files in `database/migrations/*` + + ### Custom response when magiclink is invalid When the magicLink is invalid by default the http request return a status 403. diff --git a/phpunit.postgres.xml b/phpunit.postgres.xml index 20b7212..6e9b130 100644 --- a/phpunit.postgres.xml +++ b/phpunit.postgres.xml @@ -28,5 +28,6 @@ + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b71b6b2..cbe33fb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -27,4 +27,7 @@ tests + + + diff --git a/src/MagicLinkServiceProvider.php b/src/MagicLinkServiceProvider.php index 34f2b52..650619a 100644 --- a/src/MagicLinkServiceProvider.php +++ b/src/MagicLinkServiceProvider.php @@ -17,7 +17,9 @@ public function boot() __DIR__.'/../config/magiclink.php' => config_path('magiclink.php'), ], 'config'); - $this->loadMigrationsFrom(__DIR__.'/../databases/migrations'); + $this->publishes([ + __DIR__.'/../databases/migrations' => database_path('migrations'), + ], 'migrations'); if ($this->mustLoadRoute()) { $this->loadRoutesFrom(__DIR__.'/../routes/routes.php'); diff --git a/tests/TestCase.php b/tests/TestCase.php index f35f6de..a11a29c 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,8 +12,6 @@ abstract class TestCase extends Orchestra public function setUp(): void { parent::setUp(); - - $this->setUpDatabase($this->app); } /** @@ -32,10 +30,8 @@ protected function getPackageProviders($app) * * @param \Illuminate\Foundation\Application $app */ - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { - $app['config']->set('app.key', 'base64:mJlbzP1TMXUPouK3KK6e9zS/VvxtWTfzfVlkn1JTqpM='); - $app['config']->set('auth.providers.users.model', 'MagicLink\Test\TestSupport\User'); $app['config']->set('view.paths', [__DIR__.'/stubs/resources/views']); @@ -47,13 +43,6 @@ protected function getEnvironmentSetUp($app) 'root' => __DIR__.'/stubs/storage/app_alternative', ]); - $app['config']->set('database.connections.sqlite', [ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '', - 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), - ]); - $app['config']->set('database.connections.pgsql', [ 'driver' => 'pgsql', 'host' => '127.0.0.1', @@ -72,13 +61,27 @@ protected function getEnvironmentSetUp($app) 'database' => 'test', ]); - $app['config']->set('database.default', 'sqlite'); + $app['config']->set('database.connections.testbench', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + ]); + + $driver = getenv('DB_DRIVER'); + + if($driver !== 'pgsql' && $driver !== 'mysql') { + $app['config']->set('database.default', 'testbench'); + } else { + $app['config']->set('database.default', $driver); + } - if (getenv('DB_DRIVER') === 'pgsql') { - $app['config']->set('database.default', 'pgsql'); - } elseif (getenv('DB_DRIVER') === 'mysql') { - $app['config']->set('database.default', 'mysql'); - } + } + + protected function defineDatabaseMigrations() + { + $this->loadMigrationsFrom(__DIR__.'/../databases/migrations'); + $this->setUpDatabase($this->app); } /** @@ -88,12 +91,12 @@ protected function getEnvironmentSetUp($app) */ protected function setUpDatabase($app) { - if ($app['config']->get('database.default') !== 'sqlite') { + if ($app['config']->get('database.default') !== 'testbench') { $app['db']->connection()->getSchemaBuilder()->dropIfExists('users'); $app['db']->connection()->getSchemaBuilder()->dropIfExists('migrations'); $app['db']->connection()->getSchemaBuilder()->dropIfExists('magic_links'); } - + $this->artisan('migrate'); $app['db']->connection()->getSchemaBuilder()->create('users', function (Blueprint $table) { From b29f7e3ce0796fe4a7f796a92156448518bf293f Mon Sep 17 00:00:00 2001 From: cesargb Date: Sat, 20 May 2023 16:12:50 +0000 Subject: [PATCH 07/22] Commit from GitHub Actions (style-fix) --- src/MagicLinkServiceProvider.php | 2 +- tests/TestCase.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MagicLinkServiceProvider.php b/src/MagicLinkServiceProvider.php index 650619a..1db90ef 100644 --- a/src/MagicLinkServiceProvider.php +++ b/src/MagicLinkServiceProvider.php @@ -19,7 +19,7 @@ public function boot() $this->publishes([ __DIR__.'/../databases/migrations' => database_path('migrations'), - ], 'migrations'); + ], 'migrations'); if ($this->mustLoadRoute()) { $this->loadRoutesFrom(__DIR__.'/../routes/routes.php'); diff --git a/tests/TestCase.php b/tests/TestCase.php index a11a29c..59f429b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -62,9 +62,9 @@ protected function defineEnvironment($app) ]); $app['config']->set('database.connections.testbench', [ - 'driver' => 'sqlite', + 'driver' => 'sqlite', 'database' => ':memory:', - 'prefix' => '', + 'prefix' => '', 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), ]); @@ -73,8 +73,8 @@ protected function defineEnvironment($app) if($driver !== 'pgsql' && $driver !== 'mysql') { $app['config']->set('database.default', 'testbench'); } else { - $app['config']->set('database.default', $driver); - } + $app['config']->set('database.default', $driver); + } } @@ -96,7 +96,7 @@ protected function setUpDatabase($app) $app['db']->connection()->getSchemaBuilder()->dropIfExists('migrations'); $app['db']->connection()->getSchemaBuilder()->dropIfExists('magic_links'); } - + $this->artisan('migrate'); $app['db']->connection()->getSchemaBuilder()->create('users', function (Blueprint $table) { From 0be65dc2e69c3a78f69fc7d35ad0395d2665c8b9 Mon Sep 17 00:00:00 2001 From: Cesar Date: Sat, 20 May 2023 18:24:46 +0200 Subject: [PATCH 08/22] doc: add publish migration in installation --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 855cd14..4e36854 100644 --- a/README.md +++ b/README.md @@ -36,15 +36,19 @@ You can install this package via composer using: composer require cesargb/laravel-magiclink ``` -You can then create the table by running the -migrations: +### Preparing the database + +You need to publish the migration to create the `magic_links` table: ```bash -php artisan migrate +php artisan vendor:publish --provider="MagicLink\MagicLinkServiceProvider" --tag="migrations" ``` -Note: If you have the version 1 installed, -[read this](https://github.com/cesargb/laravel-magiclink/blob/v1/README.md). +After that, you need to run migrations. + +```bash +php artisan migrate +``` ## Use case From 6bfe7ba4fe78da1299781b6d85ed7a1ef1684942 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 19:29:40 +0100 Subject: [PATCH 09/22] Bump actions/checkout from 3 to 4 (#103) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/phpstan.yml | 2 +- .github/workflows/style-fix.yml | 2 +- .github/workflows/tests.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 1c1e8ba..e1ee35b 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/style-fix.yml b/.github/workflows/style-fix.yml index 4ec8d21..a86d1c9 100644 --- a/.github/workflows/style-fix.yml +++ b/.github/workflows/style-fix.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a2d3c25..0ae630e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 From ca302bb59327d471c863edb95a2c19a3afa45054 Mon Sep 17 00:00:00 2001 From: Cesar Garcia Date: Mon, 27 Nov 2023 22:00:56 +0100 Subject: [PATCH 10/22] Add test to PHP 8.3 (#104) --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0ae630e..b99f863 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - php: [8.2, 8.1, 8.0] + php: [8.3, 8.2, 8.1, 8.0] laravel: [10.*, 9.*] dependency-version: [prefer-stable] include: From a2f62760cf54f5d5c8f7cb16c54f69baaa63d374 Mon Sep 17 00:00:00 2001 From: James Baxter Date: Wed, 29 Nov 2023 18:07:12 +0000 Subject: [PATCH 11/22] Add urlencoding to the colon in the magiclink url (#102) * urlencode the colon * update ConfigTest getTokenFromUrl to account for urlencoded colon --- src/MagicLink.php | 3 ++- tests/ConfigTest.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/MagicLink.php b/src/MagicLink.php index b1fde39..1a5a2c5 100644 --- a/src/MagicLink.php +++ b/src/MagicLink.php @@ -74,9 +74,10 @@ public function setActionAttribute($value) public function getUrlAttribute() { return url(sprintf( - '%s/%s:%s', + '%s/%s%s%s', config('magiclink.url.validate_path', 'magiclink'), $this->id, + urlencode(':'), $this->token )); } diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php index 174ae1a..4ec7c62 100644 --- a/tests/ConfigTest.php +++ b/tests/ConfigTest.php @@ -29,7 +29,7 @@ public function test_custom_token_length_bigger_than_max_value() protected function getTokenFromUrl($url) { - $parts = explode(':', $url); + $parts = explode(urlencode(':'), $url); return end($parts); } From 225c3c289ec68a66c9f93761accee132744ab85c Mon Sep 17 00:00:00 2001 From: Cesar Garcia Date: Wed, 29 Nov 2023 19:16:20 +0100 Subject: [PATCH 12/22] add test to url legacy (#105) --- tests/HttpTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/HttpTest.php b/tests/HttpTest.php index f1532e5..9572a8b 100644 --- a/tests/HttpTest.php +++ b/tests/HttpTest.php @@ -60,4 +60,17 @@ public function test_http_options_request_has_not_effects() $this->assertEquals(4, $magiclink->num_visits); } + + public function test_http_urlencode_legacy() + { + $magiclink = MagicLink::create(new ResponseAction(function () { + return 'private content'; + })); + + $urlLegacy = str_replace(urlencode(':'), ':', $magiclink->url); + + $this->get($urlLegacy) + ->assertStatus(200) + ->assertSeeText('private content'); + } } From 0f3486dea45b3c92b04cdaef6edc2307f4c7aedb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 08:44:57 +0100 Subject: [PATCH 13/22] Bump actions/cache from 3 to 4 (#109) Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/phpstan.yml | 2 +- .github/workflows/style-fix.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index e1ee35b..bb52ca9 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -21,7 +21,7 @@ jobs: - name: Cache Composer packages id: composer-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} diff --git a/.github/workflows/style-fix.yml b/.github/workflows/style-fix.yml index a86d1c9..bee1ba0 100644 --- a/.github/workflows/style-fix.yml +++ b/.github/workflows/style-fix.yml @@ -21,7 +21,7 @@ jobs: - name: Cache Composer packages id: composer-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: vendor key: ${{ runner.os }}-php-8.1-${{ hashFiles('**/composer.lock') }} From bb40fa7ea47ec3d7ca7cc8c12e3e0c2f057913a9 Mon Sep 17 00:00:00 2001 From: Laravel Shift Date: Sat, 9 Mar 2024 06:03:39 -0500 Subject: [PATCH 14/22] Laravel 11.x Compatibility (#110) * Bump dependencies for Laravel 11 * Update GitHub Actions for Laravel 11 --- .github/workflows/tests.yml | 89 ++++++++++++++++++++----------------- composer.json | 26 +++++------ 2 files changed, 61 insertions(+), 54 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b99f863..2cf616c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,46 +1,53 @@ name: tests on: - push: - pull_request: - schedule: - - cron: '0 0 * * *' + push: + pull_request: + schedule: + - cron: '0 0 * * *' jobs: - run-tests: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - php: [8.3, 8.2, 8.1, 8.0] - laravel: [10.*, 9.*] - dependency-version: [prefer-stable] - include: - - laravel: 9.* - testbench: 7.* - - laravel: 10.* - testbench: 8.* - exclude: - - laravel: 10.* - php: 8.0 - - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, exif - coverage: none - - - name: Install dependencies - run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update - composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction - - - name: Execute tests - run: composer test + run-tests: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php: [8.3, 8.2, 8.1, 8.0] + laravel: ['9.*', '10.*', '11.*'] + dependency-version: [prefer-stable] + include: + - laravel: 9.* + testbench: 7.* + - laravel: 10.* + testbench: 8.* + - laravel: 11.* + testbench: 9.* + exclude: + - laravel: 10.* + php: 8.0 + - laravel: 11.* + php: 8.1 + - laravel: 11.* + php: 8.0 + + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, exif + coverage: none + + - name: Install dependencies + run: | + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update + composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction + + - name: Execute tests + run: composer test diff --git a/composer.json b/composer.json index eb099e5..f1ae87f 100644 --- a/composer.json +++ b/composer.json @@ -11,20 +11,20 @@ ], "homepage": "https://github.com/cesargb/laravel-magiclink", "authors": [ - { - "name": "Cesar Garcia", - "email": "cesargb@gmail.com", - "homepage": "https://github.com/cesargb", - "role": "Developer" - } + { + "name": "Cesar Garcia", + "email": "cesargb@gmail.com", + "homepage": "https://github.com/cesargb", + "role": "Developer" + } ], "license": "MIT", "require": { - "php" : "^8.0", - "illuminate/auth": "^9.0|^10.0", - "illuminate/container": "^9.0|^10.0", - "illuminate/contracts": "^9.0|^10.0", - "illuminate/database": "^9.0|^10.0", + "php": "^8.0", + "illuminate/auth": "^9.0|^10.0|^11.0", + "illuminate/container": "^9.0|^10.0|^11.0", + "illuminate/contracts": "^9.0|^10.0|^11.0", + "illuminate/database": "^9.0|^10.0|^11.0", "laravel/serializable-closure": "^1.0" }, "autoload": { @@ -48,8 +48,8 @@ } }, "require-dev": { - "orchestra/testbench": "^7.0|^8.0", - "phpunit/phpunit": "^9.0", + "orchestra/testbench": "^7.0|^8.0|^9.0", + "phpunit/phpunit": "^9.0|^10.5", "nunomaduro/larastan": "^2.1", "friendsofphp/php-cs-fixer": "^3.9" }, From 5c48570c57c4181d9d0191e9bb5d5379977379f5 Mon Sep 17 00:00:00 2001 From: Cesar Date: Sat, 9 Mar 2024 12:10:10 +0100 Subject: [PATCH 15/22] fix phpunit --- phpunit.postgres.xml | 7 ------- phpunit.xml.dist | 24 +----------------------- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/phpunit.postgres.xml b/phpunit.postgres.xml index 6e9b130..d00553e 100644 --- a/phpunit.postgres.xml +++ b/phpunit.postgres.xml @@ -19,13 +19,6 @@ src/ - - - - - - - diff --git a/phpunit.xml.dist b/phpunit.xml.dist index cbe33fb..cfa7216 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,27 +1,5 @@ - - - - src/ - - - - - - - + tests From 48c8001f953df722a3c148ea5915545e87093d47 Mon Sep 17 00:00:00 2001 From: Cesar Date: Sat, 9 Mar 2024 12:17:53 +0100 Subject: [PATCH 16/22] to l11 --- tests/TestSupport/CustomAutenticable.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/TestSupport/CustomAutenticable.php b/tests/TestSupport/CustomAutenticable.php index 032274a..6fbe2e5 100644 --- a/tests/TestSupport/CustomAutenticable.php +++ b/tests/TestSupport/CustomAutenticable.php @@ -41,4 +41,14 @@ public function getRememberTokenName() { return ''; } + + public function getAuthPasswordName() + { + return ''; + } + + public function rehashPasswordIfRequired() + { + return ''; + } } From 7757e52307bc5671704fd8f3760e8e0af46c32fc Mon Sep 17 00:00:00 2001 From: Cesar Date: Sat, 9 Mar 2024 12:19:50 +0100 Subject: [PATCH 17/22] to l11 --- tests/TestSupport/CustomUserProvider.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/TestSupport/CustomUserProvider.php b/tests/TestSupport/CustomUserProvider.php index 73f9e6f..d5372b9 100644 --- a/tests/TestSupport/CustomUserProvider.php +++ b/tests/TestSupport/CustomUserProvider.php @@ -28,4 +28,14 @@ public function validateCredentials(Authenticatable $user, array $credentials) { return false; } + + public function getAuthPasswordName() + { + return ''; + } + + public function rehashPasswordIfRequired() + { + return ''; + } } From b3ccffe6e795dc0a99fd61fc362b650211287042 Mon Sep 17 00:00:00 2001 From: Cesar Date: Sat, 9 Mar 2024 12:22:40 +0100 Subject: [PATCH 18/22] to l11 --- tests/TestSupport/CustomAutenticable.php | 2 +- tests/TestSupport/CustomUserProvider.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/TestSupport/CustomAutenticable.php b/tests/TestSupport/CustomAutenticable.php index 6fbe2e5..786bf1f 100644 --- a/tests/TestSupport/CustomAutenticable.php +++ b/tests/TestSupport/CustomAutenticable.php @@ -47,7 +47,7 @@ public function getAuthPasswordName() return ''; } - public function rehashPasswordIfRequired() + public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false) { return ''; } diff --git a/tests/TestSupport/CustomUserProvider.php b/tests/TestSupport/CustomUserProvider.php index d5372b9..61dcaa4 100644 --- a/tests/TestSupport/CustomUserProvider.php +++ b/tests/TestSupport/CustomUserProvider.php @@ -34,7 +34,7 @@ public function getAuthPasswordName() return ''; } - public function rehashPasswordIfRequired() + public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false) { return ''; } From 7e6000dc9c378dafe2071015e43d86bd1009aeaf Mon Sep 17 00:00:00 2001 From: Cesar Garcia Date: Sat, 9 Mar 2024 12:29:57 +0100 Subject: [PATCH 19/22] move to larastan (#111) --- .github/workflows/phpstan.yml | 2 +- composer.json | 4 ++-- phpstan.neon.dist | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index bb52ca9..49424da 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -17,7 +17,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.2 - name: Cache Composer packages id: composer-cache diff --git a/composer.json b/composer.json index f1ae87f..e9a425d 100644 --- a/composer.json +++ b/composer.json @@ -50,8 +50,8 @@ "require-dev": { "orchestra/testbench": "^7.0|^8.0|^9.0", "phpunit/phpunit": "^9.0|^10.5", - "nunomaduro/larastan": "^2.1", - "friendsofphp/php-cs-fixer": "^3.9" + "friendsofphp/php-cs-fixer": "^3.9", + "larastan/larastan": "^2.0" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/phpstan.neon.dist b/phpstan.neon.dist index bd091d3..3f0d744 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ includes: - - ./vendor/nunomaduro/larastan/extension.neon + - ./vendor/larastan/larastan/extension.neon parameters: From 6fbdf898dce39f702c1f7303ae0b72ac09ccbab7 Mon Sep 17 00:00:00 2001 From: Cesar Date: Sun, 28 Apr 2024 16:38:18 +0200 Subject: [PATCH 20/22] fix: phpstan in test --- .gitignore | 1 + tests/TestSupport/CustomUserProvider.php | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 29b07b6..40cc916 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ /build composer.lock .phpunit.result.cache +.phpunit.cache .php-cs-fixer.cache .idea diff --git a/tests/TestSupport/CustomUserProvider.php b/tests/TestSupport/CustomUserProvider.php index 61dcaa4..f90cc36 100644 --- a/tests/TestSupport/CustomUserProvider.php +++ b/tests/TestSupport/CustomUserProvider.php @@ -36,6 +36,5 @@ public function getAuthPasswordName() public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false) { - return ''; } } From 6e22c4af22cff2d848c93a8556ea48d1972c1b03 Mon Sep 17 00:00:00 2001 From: EVOKE Date: Sun, 5 May 2024 20:25:34 +0330 Subject: [PATCH 21/22] Add base url (#108) * Add custom base url attribute and its tests * Add Custom Base URL section --- README.md | 13 +++++++++++++ src/MagicLink.php | 13 +++++++++++-- tests/MagicLinkTest.php | 10 ++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4e36854..6013018 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ once the link is visited. - [Http Response](#http-response-action) - [Controller](#controller-action) - [Custom Action](#custom-action) +- [Custom Base URL](#custom-base-url) ### Login Action @@ -241,6 +242,18 @@ $action = new MyCustomAction('Hello world'); $urlToCustomAction = MagicLink::create($action)->url; ``` +### Custom Base URL + +To set the base URL for a magic link, you can use the `baseUrl` method. This method ensures that the provided base URL has a trailing slash, making it ready for URL generation. + +```php +$magiclink = MagicLink::create($action); + +$magiclink->baseUrl("http://example.com"); + +$urlShowView = $magiclink->url; // http://example.com/magiclink/... +``` + ## Protect with an access code Optionally you can protect the resources with an access code. diff --git a/src/MagicLink.php b/src/MagicLink.php index 1a5a2c5..b428b95 100644 --- a/src/MagicLink.php +++ b/src/MagicLink.php @@ -71,10 +71,19 @@ public function setActionAttribute($value) : serialize($value); } - public function getUrlAttribute() + public function baseUrl(?string $baseUrl): self { + $this->attributes['base_url'] = rtrim($baseUrl, '/') . '/'; + return $this; + } + + public function getUrlAttribute(): string + { + $baseUrl = rtrim($this->attributes['base_url'] ?? '', '/') . '/'; // Use the stored base_url or an empty string + return url(sprintf( - '%s/%s%s%s', + '%s%s/%s%s%s', + $baseUrl, config('magiclink.url.validate_path', 'magiclink'), $this->id, urlencode(':'), diff --git a/tests/MagicLinkTest.php b/tests/MagicLinkTest.php index fec2e4c..dedc63d 100644 --- a/tests/MagicLinkTest.php +++ b/tests/MagicLinkTest.php @@ -120,4 +120,14 @@ public function test_increment_num_visits_exceeded() { $this->markTestSkipped(); } + + public function test_create_magiclink_with_custom_base_url() + { + $magiclink = MagicLink::create(new LoginAction(User::first())); + + $custom_base_url = "http://example.com"; + $magiclink->baseUrl($custom_base_url); + + $this->assertStringContainsString($custom_base_url, $magiclink->url); + } } From 78420c921cc212c2f83b96f6d9c0f58f46852ba4 Mon Sep 17 00:00:00 2001 From: cesargb Date: Sun, 5 May 2024 16:55:56 +0000 Subject: [PATCH 22/22] Commit from GitHub Actions (style-fix) --- src/MagicLink.php | 1 + tests/MagicLinkTest.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MagicLink.php b/src/MagicLink.php index b428b95..811caf1 100644 --- a/src/MagicLink.php +++ b/src/MagicLink.php @@ -74,6 +74,7 @@ public function setActionAttribute($value) public function baseUrl(?string $baseUrl): self { $this->attributes['base_url'] = rtrim($baseUrl, '/') . '/'; + return $this; } diff --git a/tests/MagicLinkTest.php b/tests/MagicLinkTest.php index dedc63d..161bfb8 100644 --- a/tests/MagicLinkTest.php +++ b/tests/MagicLinkTest.php @@ -127,7 +127,7 @@ public function test_create_magiclink_with_custom_base_url() $custom_base_url = "http://example.com"; $magiclink->baseUrl($custom_base_url); - + $this->assertStringContainsString($custom_base_url, $magiclink->url); } }