Skip to content

Commit

Permalink
Merge 579f04f into 0ebdbd4
Browse files Browse the repository at this point in the history
  • Loading branch information
mikebronner committed Dec 11, 2017
2 parents 0ebdbd4 + 579f04f commit 0fb9c1a
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,4 +1,8 @@
# Change Log
## [0.6.1] - 10 Dec 2017
### Added
- ability to exclude a page from caffinating the application via meta tag.

## [0.6.0] - 9 Dec 2017
### Added
- drip timeout check and force page refresh if timeout occurred.
Expand Down
12 changes: 11 additions & 1 deletion README.md
Expand Up @@ -64,7 +64,7 @@ For Laravel 5.2, follow the directions here: https://github.com/GeneaLabs/larave
// ];
```

## Upgrad Notes
## Upgrade Notes
### 0.6.0
This update changes the config file setting names. Please delete the published
config file `config/genealabs-laravel-caffeine.php` if it exists, and follow the
Expand Down Expand Up @@ -145,3 +145,13 @@ php artisan caffeine:publish --config
That was it! It will apply itself automatically where it finds a form with a
`_token` field, or a meta tag named "csrf-token", while pages are open in
browsers.

### Prevent Caffeination
If you would like to prevent a certain page from caffeinating your application,
then add the following meta tag:
```php
<meta name="caffeinated" content="false">
```

__This will only have effect if the page includes a form. If not, the page will
not caffeinate your application anyway.__
12 changes: 1 addition & 11 deletions routes/web.php
@@ -1,17 +1,7 @@
<?php

use GeneaLabs\LaravelCaffeine\Http\Controllers\Drip;
use GeneaLabs\LaravelCaffeine\Http\Controllers\Test;

$dripRoute = config('genealabs-laravel-caffeine.route', 'genealabs/laravel-caffeine/drip');
Route::get($dripRoute, Drip::class.'@drip');

Route::group([
'middleware' => ['web'],
'as' => 'genealabs-laravel-caffeine.',
'prefix' => 'tests'
], function () {
Route::any('form', Test::class . '@drippedForm')->name('tests.form');
Route::any('dripped-form', Test::class . '@drippedForm');
Route::any('expiring-form', Test::class . '@expiredForm');
});
Route::get($dripRoute, Drip::class.'@drip');
53 changes: 42 additions & 11 deletions src/Http/Middleware/LaravelCaffeineDripMiddleware.php
Expand Up @@ -9,21 +9,52 @@ class LaravelCaffeineDripMiddleware
public function handle(Request $request, Closure $next)
{
$response = $next($request);

$content = $response->getContent();

if (is_string($content)
&& (strpos($content, '_token')
|| (preg_match("/\<meta name=[\"\']csrf[_-]token[\"\']/", $content)))
) {
$dripper = (new Dripper);
$content = str_replace(
'</body>',
"{$dripper->html}</body>",
$content
);
$response->setContent($content);
if (! is_string($content)) {
return $response;
}

$shouldDripRegexp = $this->makeRegex([
'<meta\s+',
'(name\s*=\s*[\'"]caffeinated[\'"]\s+content\s*=\s*[\'"]false[\'"]',
'|content\s*=\s*[\'"]false[\'"]\s+name\s*=\s*[\'"]caffeinated[\'"])',
]);

$shouldNotDrip = preg_match($shouldDripRegexp, $content);

if ($shouldNotDrip) {
return $response;
}

$formTokenRegexp = $this->makeRegex([
'<input([^>]*?[\n]?)*[^>]*?name\s*=\s*[\'"]_token[\'"]',
]);
$metaTokenRegexp = $this->makeRegex([
'<meta\s+',
'name\s*=\s*[\'"]csrf[_-]token[\'"]',
]);
$hasNoFormToken = ! preg_match($formTokenRegexp, $content);
$hasNoMetaToken = ! preg_match($metaTokenRegexp, $content);

if ($hasNoFormToken && $hasNoMetaToken) {
return $response;
}

$dripper = (new Dripper);
$content = str_replace(
'</body>',
"{$dripper->html}</body>",
$content
);
$response->setContent($content);

return $response;
}

protected function makeRegex(array $regexp) : string
{
return '/' . implode('', $regexp) . '/';
}
}
16 changes: 14 additions & 2 deletions src/Providers/Service.php
Expand Up @@ -16,6 +16,10 @@ public function boot()
? ['middleware' => 'web']
: [], function () {
require __DIR__ . '/../../routes/web.php';

if (app('env') === 'testing') {
require __DIR__ . '/../../tests/routes/web.php';
}
});

$configPath = __DIR__ . '/../../config/genealabs-laravel-caffeine.php';
Expand All @@ -24,6 +28,14 @@ public function boot()
__DIR__ . '/../../resources/views',
'genealabs-laravel-caffeine'
);

if (app('env') === 'testing') {
$this->loadViewsFrom(
__DIR__ . '/../../tests/resources/views',
'genealabs-laravel-caffeine'
);
}

$this->publishes([
$configPath => config_path('genealabs-laravel-caffeine.php')
], 'config');
Expand All @@ -44,7 +56,7 @@ public function provides() : array
return ['genealabs-laravel-caffeine'];
}

private function middlewareGroupExists(string $group) : bool
protected function middlewareGroupExists(string $group) : bool
{
$routes = collect(app('router')->getRoutes()->getRoutes());

Expand All @@ -62,7 +74,7 @@ private function middlewareGroupExists(string $group) : bool
}) ?? false;
}

private function shouldRegisterMiddleware() : bool
protected function shouldRegisterMiddleware() : bool
{
return (! request()->ajax()
&& (php_sapi_name() === 'fpm-fcgi' || app('env') === 'testing'));
Expand Down
38 changes: 36 additions & 2 deletions tests/Feature/CaffeineTest.php
Expand Up @@ -7,6 +7,7 @@ class CaffeineTest extends TestCase
public function testBootstrap3TestPageCanLoad()
{
$dripRoute = config('genealabs-laravel-caffeine.route', 'genealabs/laravel-caffeine/drip');

$response = $this->get($dripRoute);

$response->assertStatus(204);
Expand Down Expand Up @@ -39,11 +40,18 @@ public function testSuccessfulDrip()

public function testExpiredDrip()
{
$dripRoute = config('genealabs-laravel-caffeine.dripInterval', 'genealabs/laravel-caffeine/drip');
$dripRoute = config(
'genealabs-laravel-caffeine.dripInterval',
'genealabs/laravel-caffeine/drip'
);
$html = $this->get(route('genealabs-laravel-caffeine.tests.form'))
->getContent();
$matches = [];
preg_match('/<meta name="csrf-token" content="(.*?)">/', $html, $matches);
preg_match(
'/<meta name="csrf-token" content="(.*?)">/',
$html,
$matches
);
$csrfToken = $matches[1];

app('session')->flush();
Expand All @@ -53,4 +61,30 @@ public function testExpiredDrip()

$response->assertStatus(404);
}

public function testDisabledCaffeination()
{
$html = $this
->get(route('genealabs-laravel-caffeine.tests.disabled-page'))
->getContent();

$isDisabled = (bool) preg_match(
'/<meta name="caffeinated" content="false">/',
$html
);
$hasDripper = (bool) preg_match(
'/\bconst caffeineSendDrip\b/',
$html
);

$this->assertTrue($isDisabled);
$this->assertFalse($hasDripper);
}

public function textNonStringReturnContent()
{
$response = $this->get(route('genealabs-laravel-caffeine.tests.null-response'));

$response->assertDontSee('const caffeineSendDrip');
}
}
@@ -1,4 +1,4 @@
<?php namespace GeneaLabs\LaravelCaffeine\Http\Controllers;
<?php namespace GeneaLabs\LaravelCaffeine\Tests\Http\Controllers;

use Illuminate\Routing\Controller;
use Illuminate\View\View;
Expand All @@ -12,4 +12,14 @@ public function drippedForm() : View

return view('genealabs-laravel-caffeine::tests.form');
}

public function disabledPage() : View
{
return view('genealabs-laravel-caffeine::tests.disabled');
}

public function nullResponse()
{
return null;
}
}
13 changes: 13 additions & 0 deletions tests/resources/views/tests/disabled.blade.php
@@ -0,0 +1,13 @@
@extends ('genealabs-laravel-caffeine::tests.layout')

@section ('meta')
<meta name="caffeinated" content="false">
@endsection

@section ('content')
<form method="post">
{{ csrf_field() }}
<input type="hidden" name="success" value="true">
<input type="submit" value="Test Form Submit">
</form>
@endsection
File renamed without changes.
Expand Up @@ -5,6 +5,8 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

@yield ('meta')

<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">

Expand All @@ -15,7 +17,9 @@
</head>
<body>
<div id="app">
@yield('content')

@yield ('content')

</div>

<!-- Scripts -->
Expand Down
18 changes: 18 additions & 0 deletions tests/routes/web.php
@@ -0,0 +1,18 @@
<?php

use GeneaLabs\LaravelCaffeine\Tests\Http\Controllers\Test;

Route::group([
'middleware' => ['web'],
'as' => 'genealabs-laravel-caffeine.',
'prefix' => 'tests'
], function () {
Route::any('form', Test::class . '@drippedForm')
->name('tests.form');
Route::any('dripped-form', Test::class . '@drippedForm');
Route::any('expiring-form', Test::class . '@expiredForm');
Route::any('disabled-page', Test::class . '@disabledPage')
->name('tests.disabled-page');
Route::any('null-response', Test::class . '@nullResponse')
->name('tests.null-response');
});

0 comments on commit 0fb9c1a

Please sign in to comment.