Skip to content
This repository has been archived by the owner on Dec 12, 2021. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
S1SYPHOS committed Oct 30, 2017
1 parent 83c4ee0 commit ce50ec2
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 1 deletion.
55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,54 @@
# kirby-sri-hash
# kirby-sri-hash
This plugin is heavily inspired by the great Kirby plugins [cachebuster](https://github.com/getkirby-plugins/cachebuster-plugin) (by Kirby team members [Bastian Allgeier](https://github.com/bastianallgeier) and [Lukas Bestle](https://github.com/lukasbestle)) as well as [fingerprint](https://github.com/iksi/kirby-fingerprint) (by [Iksi](https://github.com/iksi)).

## What's SRI?
TL;DR: I wanted to add Kirby-side [subresource integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) (SRI) for safer CDN usage - check out [these](https://getkirby.com/docs/cookbook/kirby-loves-cdn) [articles](https://www.keycdn.com/support/kirby-cdn-integration/) for starters.

**This is still experimental, and may be deleted at some point.**

## Installation
Use one of these alternatives in order to use install & use `kirby-sri-hash`:

### 1. Git Submodule

If you know your way around Git, you can download this plugin as a [submodule](https://github.com/blog/2104-working-with-submodules):

```text
git submodule add https://github.com/S1SYPHOS/kirby-sri-hash.git site/plugins/kirby-sri-hash
```

### 2. Clone or download

1. [Clone](https://github.com/S1SYPHOS/kirby-sri-hash.git) or [download](https://github.com/S1SYPHOS/kirby-sri-hash/archive/master.zip) this repository.
2. Unzip / Move the folder to `site/plugins`.

### 3. Activate the plugin
Activate the plugin with the following line in your `config.php`:

```text
c::set('sri-hash', true);
```

#### Apache
Add the following lines to your `.htaccess` (right after `RewriteBase`):

```
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.([0-9]{10})\.(js|css)$ $1.$3 [L]
```

#### NGINX
Add the following lines to your virtual host setup:

```
location /assets {
if (!-e $request_filename) {
rewrite "^/(.+)\.([0-9]{10})\.(js|css)$" /$1.$3 break;
}
}
```

**Note: Subresource integrity & cache-busting are not applied to external URLs!**

## Special Thanks
I'd like to thank everybody that's making great software - you people are awesome. Also I'm always thankful for feedback and bug reports :)
68 changes: 68 additions & 0 deletions core/css.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace S1SYPHOS\SRI;

use Asset;
use f;
use html;

class CSS extends \Kirby\Component\CSS {

/**
* Builds the html link tag for the given css file
*
* @param string $url
* @param string|array $media Either a media string or an array of attributes
* @return string
*/

public function tag($url, $media = null) {

if(is_array($url)) {
$css = array();
foreach($url as $u) $css[] = $this->tag($u, $media);
return implode(PHP_EOL, $css) . PHP_EOL;
}

// auto template css files
if($url == '@auto') {
$file = $this->kirby->site()->page()->template() . '.css';
$root = $this->kirby->roots()->autocss() . DS . $file;
$url = $this->kirby->urls()->autocss() . '/' . $file;
if(!file_exists($root)) return false;
$url = preg_replace('#^' . $this->kirby->urls()->index() . '/#', null, $url);
}

$url = ltrim($url, '/');

if (file_exists($url)) {
// generate sri hash for css files
$cssInput = (new Asset($url))->content();
$cssIntegrity = checksum($cssInput);

// add timestamp for cache-busting
$modified = filemtime($url);
$filename = f::name($url) . '.' . $modified . '.' . f::extension($url);
$dirname = f::dirname($url);
$url = ($dirname === '.') ? $filename : $dirname . '/' . $filename;
}

// build the array of HTML attributes
$attr = array(
'rel' => 'stylesheet',
'href' => url($url),
'integrity' => $cssIntegrity // inject generated sri hash
);

if(is_array($media)) {
// merge array with custom options
$attr = array_merge($attr, $media);
} else if(is_string($media)) {
// if there's no such array, just set media key
$attr['media'] = $media;
}

// return the proper 'link' tag
return html::tag('link', null, $attr);
}
}
67 changes: 67 additions & 0 deletions core/js.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace S1SYPHOS\SRI;

use Asset;
use f;
use html;

class JS extends \Kirby\Component\JS {

/**
* Builds the html script tag for the given javascript file
*
* @param string $src
* @param boolean|array $async Either true for the async attribute or an array of attributes
* @return string
*/

public function tag($src, $async = false) {

if(is_array($src)) {
$js = array();
foreach($src as $s) $js[] = $this->tag($s, $async);
return implode(PHP_EOL, $js) . PHP_EOL;
}

// auto template css files
if($src == '@auto') {
$file = $this->kirby->site()->page()->template() . '.js';
$root = $this->kirby->roots()->autojs() . DS . $file;
$src = $this->kirby->urls()->autojs() . '/' . $file;
if(!file_exists($root)) return false;
$src = preg_replace('#^' . $this->kirby->urls()->index() . '/#', null, $src);
}

$src = ltrim($src, '/');

if (file_exists($src)) {
// generate sri hash for css files
$jsInput = (new Asset($src))->content();
$jsIntegrity = checksum($jsInput);

// add timestamp for cache-busting
$modified = filemtime($src);
$filename = f::name($src) . '.' . $modified . '.' . f::extension($src);
$dirname = f::dirname($src);
$src = ($dirname === '.') ? $filename : $dirname . '/' . $filename;
}

// build the array of HTML attributes
$attr = array(
'src' => url($src),
'integrity' => $jsIntegrity // inject generated sri hash
);

if(is_array($async)) {
// merge array with custom options
$attr = array_merge($attr, $async);
} else if($async === true) {
// if there's no such array, just set async key
$attr['async'] = true;
}

// return the proper 'script' tag
return html::tag('script', '', $attr);
}
}
25 changes: 25 additions & 0 deletions kirby-sri-hash.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* Adding SRI Hash to css & js files and cache-busting them
*
* @version 0.1.0
* @author S1SYPHOS <[email protected]>
*/

if(!c::get('sri-hash')) return;

function checksum($input) {
$hash = hash('sha512', $input, true);
$hash_base64 = base64_encode($hash);

return "sha512-$hash_base64";
}

load([
's1syphos\\sri\\css' => __DIR__ . DS . 'core' . DS . 'css.php',
's1syphos\\sri\\js' => __DIR__ . DS . 'core' . DS . 'js.php'
]);

kirby()->set('component', 'css', 'S1SYPHOS\\SRI\\CSS');
kirby()->set('component', 'js', 'S1SYPHOS\\SRI\\JS');
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "sri-hash",
"description": "Kirby SRI Hash & Cache-bust Plugin",
"author": "S1SYPHOS <[email protected]>",
"version": "0.1.0",
"type": "kirby-plugin",
"license": "MIT"
}

0 comments on commit ce50ec2

Please sign in to comment.