Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Change Log
## [0.6.0] - 9 Dec 2017
### Added
- drip timeout check and force page refresh if timeout occurred.

### Changed
- config file setting names to be more explicit.
- middleware is injected only when called from a web page or during testing.
95 changes: 77 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ I chose this approach to keep the integrity of site-security, by avoiding the

## Considerations
### Routes
This package adds the routes under `genealabs/laravel-caffeine`. Please verify
that these don't collide with your existing routes.
This package adds the routes under `genealabs/laravel-caffeine`.

### Dependencies
- Your project must be running one of the following Laravel versions:
Expand All @@ -48,7 +47,6 @@ For Laravel 5.2, follow the directions here: https://github.com/GeneaLabs/larave
composer require genealabs/laravel-caffeine
```


2. **This is only required for Laravel 5.4 or below:**
Add the service provider entry in `config/app.php`:
```php
Expand All @@ -57,32 +55,93 @@ For Laravel 5.2, follow the directions here: https://github.com/GeneaLabs/larave
// ],
```

3. If you have previously registered the middleware, please remove the following
3. If you are running 5.5 or above, remove the providers entry from `config/app.php`.
4. If you have previously registered the middleware, please remove the following
middleware from `app/Http/Kernel.php`:
```php
// protected $middleware = [
GeneaLabs\LaravelCaffeine\Http\Middleware\LaravelCaffeineDripMiddleware::class,
// ];
```

## Upgrad 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
configuration instructions below.

## Configuration
The following elements are configurable:
- **domain:** (default: `url('/')`) Change to point to a different domain than
your app. This is useful if you are behind a proxy or load-balancer. ___Do not use
the `url()` helper in the config file.___
- **route:** (default: `genealabs/laravel-caffeine/drip`) Change to customize
the drip URL in the browser. This is just cosmetic.
- **dripIntervalInMilliSeconds:** (default: 5 mins) Change to configure the drip
interval.
```php
return [
/*
|--------------------------------------------------------------------------
| Drip Interval
|--------------------------------------------------------------------------
|
| Here you may configure the interval with which Caffeine for Laravel
| keeps the session alive. By default this is 5 minutes (expressed
| in milliseconds). This needs to be shorter than your session
| lifetime value configured set in "config/session.php".
|
| Default: 300000 (int)
|
*/
'dripInterval' => 300000,

/*
|--------------------------------------------------------------------------
| Domain
|--------------------------------------------------------------------------
|
| You may optionally configure a separate domain that you are running
| Caffeine for Laravel on. This may be of interest if you have a
| monitoring service that queries other apps. Setting this to
| null will use the domain of the current application.
|
| Default: null (null|string)
|
*/
'domain' => null,

/*
|--------------------------------------------------------------------------
| Drip Endpoint URL
|--------------------------------------------------------------------------
|
| Sometimes you may wish to white-label your app and not expose the AJAX
| request URLs as belonging to this package. To achieve that you can
| rename the URL used for dripping caffeine into your application.
|
| Default: 'genealabs/laravel-caffeine/drip' (string)
|
*/
'route' => 'genealabs/laravel-caffeine/drip', // Customizable end-point URL

/*
|--------------------------------------------------------------------------
| Checking for Lapsed Drips
|--------------------------------------------------------------------------
|
| If the browser is put to sleep on (for example on mobil devices or
| laptops), it will still cause an error when trying to submit the
| form. To avoid this, we force-reload the form 2 minutes prior
| to session time-out or later. Setting this setting to 0
| will disable this check if you don't want to use it.
|
| Default: 2000 (int)
|
*/
'outdatedDripCheckInterval' => 2000,

];
```

___Only publish the config file if you need to customize it___:
```sh
php artisan vendor:publish --tag=genealabs-laravel-caffeine
php artisan caffeine:publish --config
```

You can now change the default value in `config/genealabs-laravel-caffeine.php` as desired. Deleting the
`config/genealabs-laravel-caffeine.php` file will revert back to the default settings.

## Usage
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.
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.
65 changes: 60 additions & 5 deletions config/genealabs-laravel-caffeine.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,64 @@
<?php

return [
'dripIntervalInMilliSeconds' => 300000, // Drip every 5 minutes
'domain' => null, // defaults to url('/')
'route' => 'genealabs/laravel-caffeine/drip', // Can be customized
'thresholdDifference' => 10000, // When the drip will be considered old to reload the page
'checkLastDripInterval' => 2000 // How often we will check if the drip is old
/*
|--------------------------------------------------------------------------
| Drip Interval
|--------------------------------------------------------------------------
|
| Here you may configure the interval with which Caffeine for Laravel
| keeps the session alive. By default this is 5 minutes (expressed
| in milliseconds). This needs to be shorter than your session
| lifetime value configured set in "config/session.php".
|
| Default: 300000 (int)
|
*/
'dripInterval' => 300000,

/*
|--------------------------------------------------------------------------
| Domain
|--------------------------------------------------------------------------
|
| You may optionally configure a separate domain that you are running
| Caffeine for Laravel on. This may be of interest if you have a
| monitoring service that queries other apps. Setting this to
| null will use the domain of the current application.
|
| Default: null (null|string)
|
*/
'domain' => null,

/*
|--------------------------------------------------------------------------
| Drip Endpoint URL
|--------------------------------------------------------------------------
|
| Sometimes you may wish to white-label your app and not expose the AJAX
| request URLs as belonging to this package. To achieve that you can
| rename the URL used for dripping caffeine into your application.
|
| Default: 'genealabs/laravel-caffeine/drip' (string)
|
*/
'route' => 'genealabs/laravel-caffeine/drip', // Customizable end-point URL

/*
|--------------------------------------------------------------------------
| Checking for Lapsed Drips
|--------------------------------------------------------------------------
|
| If the browser is put to sleep on (for example on mobil devices or
| laptops), it will still cause an error when trying to submit the
| form. To avoid this, we force-reload the form 2 minutes prior
| to session time-out or later. Setting this setting to 0
| will disable this check if you don't want to use it.
|
| Default: 2000 (int)
|
*/
'outdatedDripCheckInterval' => 2000,

];
30 changes: 30 additions & 0 deletions resources/views/script.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script>
let lastCheck = new Date();
const caffeineSendDrip = function () {
const ajax = window.XMLHttpRequest
? new XMLHttpRequest
: new ActiveXObject('Microsoft.XMLHTTP');

ajax.onreadystatechange = function () {
if (ajax.readyState === 4 && ajax.status === 204) {
lastCheck = new Date();
}
};

ajax.open('GET', '{{ $url }}');
ajax.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
ajax.send();
}

setInterval(function () {
caffeineSendDrip();
}, {{ $interval }});

if ({{ $ageCheckInterval }} > 0) {
setInterval(function () {
if (new Date() - lastCheck >= {{ $ageCheckInterval + $ageThreshold }}) {
location.reload(true);
}
}, {{ $ageCheckInterval }});
}
</script>
57 changes: 18 additions & 39 deletions src/Dripper.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,38 @@

use Jenssegers\Model\Model;

/**
* @property string $html
* @property string $interval
* @property string $url
*/
class Dripper extends Model
{
public function getHtmlAttribute() : string
{

return '<script>'
. "let ld = new Date();"
. "function caffeineSendDrip () {"
. " let e = window.XMLHttpRequest ? new XMLHttpRequest : new ActiveXObject('Microsoft.XMLHTTP');"
. " e.onreadystatechange = function () {"
. " if (e.readyState === 4 && e.status === 204) {"
. " ld = new Date();"
. " }"
. " };"
. " e.open('GET', '{$this->url}', !0);"
. " e.setRequestHeader('X-Requested-With', 'XMLHttpRequest');"
. " e.send();"
. "}"
. "setInterval(function () { caffeineSendDrip(); }, $this->interval);"
. "setInterval(function () {"
. " if (new Date() - ld >= $this->interval + $this->threshold) {"
. " location.reload(true);"
. " }"
. "}, $this->checkInterval);"
. "</script>";
$html = (string) view('genealabs-laravel-caffeine::script')
->with([
'ageCheckInterval' => $this->ageCheckInterval,
'ageThreshold' => $this->ageThreshold,
'interval' => $this->interval,
'url' => $this->url,
]);
return $html;
}

public function getIntervalAttribute() : string
public function getAgeCheckIntervalAttribute() : int
{
return config(
'genealabs-laravel-caffeine.dripIntervalInMilliSeconds',
300000
'genealabs-laravel-caffeine.outdatedDripCheckInterval',
2000
);
}
public function getThresholdAttribute() : int

public function getAgeThresholdAttribute() : int
{
return config(
'genealabs-laravel-caffeine.thresholdDifference',
10000
);
return (config('session.lifetime', 32) - 2) * 60000;
}
public function getCheckIntervalAttribute() : int

public function getIntervalAttribute() : string
{
return config(
'genealabs-laravel-caffeine.checkLastDripInterval',
2000
'genealabs-laravel-caffeine.dripInterval',
300000
);
}

Expand Down
13 changes: 11 additions & 2 deletions src/Providers/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

use GeneaLabs\LaravelCaffeine\Console\Commands\Publish;
use GeneaLabs\LaravelCaffeine\Http\Middleware\LaravelCaffeineDripMiddleware;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Routing\Route;
use Illuminate\Support\ServiceProvider;

class Service extends ServiceProvider
{
Expand Down Expand Up @@ -33,7 +34,9 @@ public function register()
$this->commands(Publish::class);
$this->mergeConfigFrom(__DIR__ . '/../../config/genealabs-laravel-caffeine.php', 'genealabs-laravel-caffeine');

app('Illuminate\Contracts\Http\Kernel')->pushMiddleware('\GeneaLabs\LaravelCaffeine\Http\Middleware\LaravelCaffeineDripMiddleware');
if ($this->shouldRegisterMiddleware()) {
app(Kernel::class)->pushMiddleware('\\' . LaravelCaffeineDripMiddleware::class);
}
}

public function provides() : array
Expand All @@ -58,4 +61,10 @@ private function middlewareGroupExists(string $group) : bool
return $carry;
}) ?? false;
}

private function shouldRegisterMiddleware() : bool
{
return (! request()->ajax()
&& (php_sapi_name() === 'fpm-fcgi' || app('env') === 'testing'));
}
}
2 changes: 1 addition & 1 deletion tests/Feature/CaffeineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function testBootstrap3TestPageCanLoad()

public function testMiddlewareInjectsDripScript()
{
$expectedResult = "<script>setInterval(function(){var e=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject('Microsoft.XMLHTTP');e.open('GET','/genealabs/laravel-caffeine/drip',!0);e.setRequestHeader('X-Requested-With','XMLHttpRequest');e.send();}, 50000);</script>";
$expectedResult = file_get_contents(__DIR__ . '/../Fixtures/expired_script.txt');

$response = $this->get(route('genealabs-laravel-caffeine.tests.form'));

Expand Down
30 changes: 30 additions & 0 deletions tests/Fixtures/expired_script.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script>
let lastCheck = new Date();
const caffeineSendDrip = function () {
const ajax = window.XMLHttpRequest
? new XMLHttpRequest
: new ActiveXObject('Microsoft.XMLHTTP');

ajax.onreadystatechange = function () {
if (ajax.readyState === 4 && ajax.status === 204) {
lastCheck = new Date();
}
};

ajax.open('GET', '/genealabs/laravel-caffeine/drip');
ajax.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
ajax.send();
}

setInterval(function () {
caffeineSendDrip();
}, 300000);

if (2000 > 0) {
setInterval(function () {
if (new Date() - lastCheck >= -58000) {
location.reload(true);
}
}, 2000);
}
</script>
Loading