├── config ├── .gitkeep └── scanner.php ├── .styleci.yml ├── screenshot.png ├── .editorconfig ├── src ├── ArtisanScanServiceProvider.php └── Commands │ ├── Performance.php │ └── Launch.php ├── LICENSE.md ├── composer.json └── README.md /config/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel 2 | 3 | disabled: 4 | - single_class_element_per_statement 5 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appstract/laravel-artisan-scan/HEAD/screenshot.png -------------------------------------------------------------------------------- /config/scanner.php: -------------------------------------------------------------------------------- 1 | 'www.example.com', 5 | 'views' => base_path('resources/views'), 6 | 'assets' => [ 7 | 'css' => public_path('css/app.css'), 8 | 'js' => public_path('js/app.js'), 9 | ], 10 | ]; 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_size = 4 9 | indent_style = space 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /src/ArtisanScanServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 15 | $this->publishes([ 16 | __DIR__.'/../config/scanner.php' => config_path('scanner.php'), 17 | ], 'config'); 18 | 19 | $this->commands([ 20 | Commands\Performance::class, 21 | Commands\Launch::class, 22 | ]); 23 | } 24 | } 25 | 26 | /** 27 | * Register the application services. 28 | */ 29 | public function register() 30 | { 31 | $this->mergeConfigFrom(__DIR__.'/../config/scanner.php', 'scanner'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) Appstract 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "appstract/laravel-artisan-scan", 3 | "description": ":package_description", 4 | "keywords": [ 5 | "appstract", 6 | "laravel-artisan-scan" 7 | ], 8 | "homepage": "https://github.com/appstract/laravel-artisan-scan", 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Bob Krijnen", 13 | "email": "hello@appstract.team", 14 | "homepage": "https://appstract.team", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^7.0" 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "5.*" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Appstract\\ArtisanScan\\": "src" 27 | } 28 | }, 29 | "autoload-dev": { 30 | "psr-4": { 31 | "Appstract\\ArtisanScan\\Test\\": "tests" 32 | } 33 | }, 34 | "scripts": { 35 | "test": "vendor/bin/phpunit" 36 | }, 37 | "config": { 38 | "sort-packages": true 39 | }, 40 | "extra": { 41 | "laravel": { 42 | "providers": [ 43 | "Appstract\\ArtisanScan\\ArtisanScanServiceProvider" 44 | ], 45 | "aliases": { 46 | "Alias": "Appstract\\ArtisanScan\\ScanFacade" 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Commands/Performance.php: -------------------------------------------------------------------------------- 1 | error('Opcache is not enabled'); 38 | } 39 | 40 | if (! File::exists(base_path('bootstrap/cache/config.php'))) { 41 | if ($this->confirm('Create a cache file for faster configuration loading?')) { 42 | $this->call('config:cache'); 43 | } 44 | } 45 | 46 | if (! File::exists(base_path('bootstrap/cache/routes.php'))) { 47 | if ($this->confirm('Do you wish to create a route cache file for faster route registration?')) { 48 | $this->call('route:cache'); 49 | } 50 | } 51 | 52 | if ($this->confirm('Optimize the framework for better performance?')) { 53 | $this->call('optimize'); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Wip] Laravel artisan scan 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/appstract/laravel-artisan-scan.svg?style=flat-square)](https://packagist.org/packages/appstract/laravel-artisan-scan) 4 | [![Total Downloads](https://img.shields.io/packagist/dt/appstract/laravel-artisan-scan.svg?style=flat-square)](https://packagist.org/packages/appstract/laravel-artisan-scan) 5 | [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) 6 | [![Build Status](https://img.shields.io/travis/appstract/laravel-artisan-scan/master.svg?style=flat-square)](https://travis-ci.org/appstract/laravel-artisan-scan) 7 | 8 | # Work in progress 9 | 10 | This package allows you to check several things in just one command, such as: 11 | - mixed content 12 | - SSL certificate 13 | - Minified assets 14 | 15 | However, keep in mind that this is still a work in progress, feel free to check it out tho. 16 | 17 | 18 | ## Installation 19 | 20 | You can install the package via composer: 21 | 22 | ``` bash 23 | composer require appstract/laravel-artisan-scan 24 | ``` 25 | 26 | ## Usage 27 | 28 | ``` bash 29 | php artisan scan:launch 30 | ``` 31 | 32 | ![Screenshot](screenshot.png?raw=true) 33 | 34 | ## Testing 35 | 36 | ``` bash 37 | $ composer test 38 | ``` 39 | 40 | ## Contributing 41 | 42 | Contributions are welcome, [thanks to y'all](https://github.com/appstract/laravel-blade-directives/graphs/contributors) :) 43 | 44 | ## About Appstract 45 | 46 | Appstract is a small team from The Netherlands. We create (open source) tools for webdevelopment and write about related subjects on [Medium](https://medium.com/appstract). You can [follow us on Twitter](https://twitter.com/teamappstract), [buy us a beer](https://www.paypal.me/teamappstract/10) or [support us on Patreon](https://www.patreon.com/appstract). 47 | 48 | ## License 49 | 50 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 51 | -------------------------------------------------------------------------------- /src/Commands/Launch.php: -------------------------------------------------------------------------------- 1 | checkSsl(); 41 | $this->addTableSeperator(); 42 | 43 | // Search sources for http://. Replace by https:// 44 | $this->searchForHttp(); 45 | $this->addTableSeperator(); 46 | 47 | // Is yarn.lock present? 48 | $this->hasYarn(); 49 | $this->addTableSeperator(); 50 | 51 | // Remove all console.log lines in scripts 52 | $this->removeConsoleLogs(); 53 | $this->addTableSeperator(); 54 | 55 | // Check if assets are minified 56 | $this->hasMinifiedAssets(); 57 | $this->addTableSeperator(); 58 | 59 | // Are 404, 500 and 503 pages provided? 60 | $this->hasErrorPages(); 61 | 62 | // Render 63 | return $this->table(['Category', 'Results'], $this->results); 64 | } 65 | 66 | /** 67 | * [checkSsl description]. 68 | * @param [type] $domain [description] 69 | * @return [type] [description] 70 | */ 71 | public function checkSsl() 72 | { 73 | if ((env('APP_ENV') == 'local')) { 74 | return; 75 | } 76 | 77 | $this->results = array_add($this->results, 'ssl', ['SSL certificate']); 78 | 79 | try { 80 | $domain = config('scanner.domain'); 81 | $stream = stream_context_create(['ssl' => ['capture_peer_cert' => true]]); 82 | $read = fopen($domain, 'rb', false, $stream); 83 | } catch (\Exception $e) { 84 | return $this->results['ssl'][] = 'Invalid'; 85 | } 86 | 87 | // Check that SSL certificate is not null 88 | // peer_certificate should be for example "OpenSSL X.509 resource @342" 89 | $params = stream_context_get_params($read); 90 | $cert = $params['options']['ssl']['peer_certificate']; 91 | 92 | $this->results['ssl'] = $cert ? 'Valid' : 'Invalid'; 93 | } 94 | 95 | /** 96 | * Search For Http. 97 | */ 98 | public function searchForHttp() 99 | { 100 | $dir = config('scanner.views'); 101 | $http = 0; 102 | $output = ''; 103 | 104 | $di = new \RecursiveDirectoryIterator($dir); 105 | 106 | foreach (new \RecursiveIteratorIterator($di) as $filename => $file) { 107 | if (File::extension($file) == 'php') { 108 | if (preg_match_all('/http:\/\//', File::get($file), $matches)) { 109 | $output .= $filename; 110 | $http++; 111 | } 112 | } 113 | } 114 | 115 | $this->results = array_add($this->results, 'http', ["Mixed Content ($http found)", $output]); 116 | } 117 | 118 | /** 119 | * Remove console.logs from js file. 120 | */ 121 | public function hasYarn() 122 | { 123 | $this->results['yarn'] = ['Yarn.lock', (File::exists(base_path('yarn.lock'))) ? 'Present' : 'File not found']; 124 | } 125 | 126 | /** 127 | * Remove console.logs from js file. 128 | */ 129 | public function removeConsoleLogs() 130 | { 131 | $file = File::get(public_path('js/app.js')); 132 | $regex = '/(?(?:\/\/)?\s*console\.[^;]+;)/'; 133 | $count = preg_match_all($regex, $file, $matches); 134 | 135 | File::put(public_path('js/app.js'), preg_replace($regex, '', $file)); 136 | 137 | $this->results['console.log'] = ['console.log', "$count removed"]; 138 | } 139 | 140 | /** 141 | * Check for minified asset files (css/js). 142 | */ 143 | public function hasMinifiedAssets() 144 | { 145 | $output = collect(config('scanner.assets'))->map(function ($value, $key) { 146 | $fp = fopen($value, 'r'); 147 | 148 | while (! feof($fp)) { 149 | fgets($fp); 150 | } 151 | 152 | fclose($fp); 153 | 154 | $bytes = round(File::size($value) / 1024).'KB'; 155 | 156 | return ($bytes > 50) ? "$key: $bytes" : "$key: $bytes"; 157 | })->implode("\n"); 158 | 159 | $this->results['assets'] = ['Minified assets', $output]; 160 | } 161 | 162 | /** 163 | * Remove console.logs from js file. 164 | */ 165 | public function hasErrorPages() 166 | { 167 | $output = collect([404, 500, 503])->map(function ($value, $key) { 168 | return (! File::exists(base_path("resources/views/errors/$value.blade.php"))) 169 | ? "$value not found" 170 | : "$value present"; 171 | })->implode("\n"); 172 | 173 | $this->results['errors'] = ['Error pages', $output]; 174 | } 175 | 176 | /** 177 | * [addTableSeperator description]. 178 | */ 179 | protected function addTableSeperator() 180 | { 181 | $this->results[] = new TableSeparator(); 182 | } 183 | } 184 | --------------------------------------------------------------------------------