Compare commits

..

1 commit

Author SHA1 Message Date
Robin Choffardet
71d1794d56 Behave like a terminal (#20)
*  add history feature

* 📝 merge submit event

* 📝 remove else keyword by making use of early return

* 📝 end file with a newline

*  add limit to history (1000 elements max)

*  behave like a terminal

*  add redirection for "old" sharable url
2017-10-30 18:58:27 +01:00
89 changed files with 3593 additions and 8433 deletions

View file

@ -5,8 +5,6 @@ APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://dnsrecords.io.dev
BUGSNAG_API_KEY=
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306

15
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,15 @@
# Contributing
Contributions are **welcome** and will be fully **credited**. We accept contributions via Pull Requests on [Github](https://github.com/spatie/laravel-medialibrary).
## Pull Requests
- **[PSR-2 Coding Standard.](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** The easiest way to apply the conventions is to install [PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer).
- **Add tests!** Your patch won't be accepted if it doesn't have tests.
- **Document any change in behaviour.** Make sure the `README.md` and any other relevant documentation are kept up-to-date.
- **Consider our release cycle.** We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
- **Create feature branches.** Don't ask us to pull from your master branch.
- **One pull request per feature.** If you want to do more than one thing, send multiple pull requests.
- **Send coherent history.** Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
*Happy coding!*

View file

@ -1,4 +1,7 @@
@setup
require __DIR__.'/vendor/autoload.php';
(new \Dotenv\Dotenv(__DIR__, '.env'))->load();
$server = "dnsrecords.io";
$userAndServer = 'forge@'. $server;
$repository = "spatie/{$server}";
@ -79,7 +82,7 @@ yarn
@task('generateAssets', ['on' => 'remote'])
{{ logMessage("🌅 Generating assets...") }}
cd {{ $newReleaseDir }};
yarn run production --progress false
yarn run production -- --progress false
@endtask
@task('updateSymlinks', ['on' => 'remote'])
@ -98,6 +101,7 @@ ln -nfs {{ $baseDir }}/.env .env;
{{ logMessage("✨ Optimizing installation...") }}
cd {{ $newReleaseDir }};
php artisan clear-compiled;
php artisan optimize;
@endtask
@task('blessNewRelease', ['on' => 'remote'])

View file

@ -1,39 +1,39 @@
[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/support-ukraine.svg?t=1" />](https://supportukrainenow.org)
# dnsrecords.io
![screenshot](https://spatie.github.io/dnsrecords.io/screenshot.png)
This repo contains the source code of [https://dnsrecords.io](https://dnsrecords.io)
## Support us
[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/dnsrecordsio.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/dnsrecords.io)
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
## Contributing
Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
## Security
If you discover any security related issues, please email [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.
If you discover any security related issues, please email [freek@spatie.be](mailto:freek@spatie.be) instead of using the issue tracker.
## Postcardware
You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.
Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.
Our address is: Spatie, Samberstraat 69D, 2060 Antwerp, Belgium.
We publish all received postcards [on our company website](https://spatie.be/en/opensource/postcards).
## Credits
- [Sebastian De Deyne](https://github.com/sebdeyne)
- [Willem Van Bockstal](https://github.com/willemvb)
- [Willem Van Bockstal](https://github.com/willemvanbockstal)
- [Freek Van der Herten](https://github.com/freekmurze)
- [All Contributors](../../contributors)
## Support us
Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects [on our website](https://spatie.be/opensource).
Does your business depend on our contributions? Reach out and support us on [Patreon](https://www.patreon.com/spatie).
All pledges will be dedicated to allocating workforce on maintenance and new awesome stuff.
### License
The code in this repo and The Laravel framework are open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)

View file

@ -3,7 +3,6 @@
namespace App\Http\Controllers;
use App\Services\Commands\CommandChain;
use Illuminate\Http\Request;
class HomeController extends Controller
{
@ -12,14 +11,14 @@ class HomeController extends Controller
return view('home.index');
}
public function submit($command = null, Request $request)
public function submit($command)
{
$command = $request['command'] ?? $command;
if (!$command) {
return $this->index();
if(request()->header('Accept') !== 'application/json')
{
return redirect()->to('/#'.$command);
}
return (new CommandChain())->perform(strtolower($command));
}
}

View file

@ -51,15 +51,12 @@ class Kernel extends HttpKernel
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'logRequest' => \Spatie\HttpLogger\Middlewares\HttpLogger::class,
'sanitizeCommand' => \App\Http\Middleware\SanitizeCommand::class,
];
}

View file

@ -1,19 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function redirectTo($request)
{
return route('login');
}
}

View file

@ -1,36 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Spatie\Dns\Dns;
class SanitizeCommand
{
public function handle(Request $request, Closure $next)
{
$command = $request->command ?? $request->route('command');
$sanitizedCommand = $this->sanitizeCommand($command);
$sanitizedCommand = str_replace('...', '', $sanitizedCommand);
if ($command !== $sanitizedCommand) {
return redirect()->action('HomeController@submit', ['command' => $sanitizedCommand]);
}
return $next($request);
}
protected function sanitizeCommand(?string $command = ''): ?string
{
$cleanCommand = strip_tags($command);
if (!$cleanCommand) {
return null;
}
return (new Dns(strip_tags($cleanCommand)))->getDomain();
}
}

View file

@ -19,5 +19,11 @@ class TrustProxies extends Middleware
*
* @var array
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
protected $headers = [
Request::HEADER_FORWARDED => 'FORWARDED',
Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
];
}

View file

@ -6,13 +6,6 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
*
* @var bool
*/
protected $addHttpCookie = true;
/**
* The URIs that should be excluded from CSRF verification.
*

View file

@ -23,7 +23,7 @@ class AppServiceProvider extends ServiceProvider
*/
public function register()
{
$this->app->alias('bugsnag.multi', \Psr\Log\LoggerInterface::class);
$this->app->alias('bugsnag.multi', \Illuminate\Contracts\Logging\Log::class);
$this->app->alias('bugsnag.multi', \Psr\Log\LoggerInterface::class);
}
}

View file

@ -15,9 +15,7 @@ class CommandChain
protected $commands = [
Manual::class,
Localhost::class,
Clear::class,
Ip::class,
Doom::class,
DnsLookup::class,
];

View file

@ -1,19 +0,0 @@
<?php
namespace App\Services\Commands\Commands;
use App\Services\Commands\Command;
use Symfony\Component\HttpFoundation\Response;
class Clear implements Command
{
public function canPerform(string $command): bool
{
return $command === 'clear';
}
public function perform(string $command): Response
{
return redirect('/');
}
}

View file

@ -3,8 +3,7 @@
namespace App\Services\Commands\Commands;
use App\Services\Commands\Command;
use Exception;
use Spatie\Dns\Dns;
use App\Services\DnsRecordsRetriever;
use Symfony\Component\HttpFoundation\Response;
class DnsLookup implements Command
@ -16,24 +15,24 @@ class DnsLookup implements Command
public function perform(string $command): Response
{
$dns = new Dns($command);
$dnsRecordsRetriever = new DnsRecordsRetriever();
try {
$dnsRecords = $dns->getRecords();
$domain = $dns->getDomain($command);
} catch (Exception $e) {
$dnsRecords = '';
}
$dnsRecords = $dnsRecordsRetriever->retrieveDnsRecords($command);
if ($dnsRecords === '') {
$errorText = __('errors.noDnsRecordsFound', ['domain' => $domain ?? null]);
$domain = $dnsRecordsRetriever->getSanitizedDomain($command);
flash()->error($errorText);
$errorText = __('errors.noDnsRecordsFound', compact('domain'));
return redirect('/');
return response([
'message' => $errorText,
'type' => 'danger',
]);
}
return response()->view('home.index', ['output' => $dnsRecords, 'domain' => $domain ]);
return response([
'message' => htmlentities($dnsRecords),
'type' => 'default',
]);
}
}

View file

@ -1,19 +0,0 @@
<?php
namespace App\Services\Commands\Commands;
use App\Services\Commands\Command;
use Symfony\Component\HttpFoundation\Response;
class Doom implements Command
{
public function canPerform(string $command): bool
{
return $command === 'doom';
}
public function perform(string $command): Response
{
return redirect('https://js-dos.com/games/doom.exe.html');
}
}

View file

@ -14,8 +14,9 @@ class Ip implements Command
public function perform(string $command): Response
{
$output = 'Your ip address is ' . request()->ip() . '.';
return response()->view('home.index', ['output'=> $output]);
return response([
'message' => 'Your ip address is ' . request()->ip() . '.',
'type' => 'default',
]);
}
}

View file

@ -14,8 +14,9 @@ class Localhost implements Command
public function perform(string $command): Response
{
flash()->error("Please try someone else's domain.");
return back();
return response([
'message' => 'Please try someone else\'s domain.',
'type' => 'danger',
]);
}
}

View file

@ -19,11 +19,11 @@ class Manual implements Command
"Enter 'ip' to check your own address.",
"Enter 'clear' to wipe the screen.",
"Enter 'doom' to play Doom.",
"Drag this bookmarklet to your toolbar to <a class=\"bookmarklet\" href=\"javascript:location.href='https://dnsrecords.io/'+location.hostname;\">lookup DNS records</a> for sites you're visiting."
])->implode('<br>');
flash()->message($manualText, 'info');
return redirect('/');
return response([
'message' => $manualText,
'type' => 'info'
]);
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace App\Services;
use Exception;
use Symfony\Component\Process\Process;
class DnsRecordsRetriever
{
public function retrieveDnsRecords(string $domain): string
{
$domain = $this->getSanitizedDomain($domain);
return cache()->remember(md5($domain), 1, function () use ($domain) {
return $this->retrieveRawDnsRecords($domain);
});
}
public function getSanitizedDomain(string $domain): string
{
$domain = str_replace(['http://', 'https://'], '', $domain);
$domain = parse_url("http://{$domain}", PHP_URL_HOST);
if (function_exists('idn_to_ascii')) {
$domain = idn_to_ascii($domain) ?? $domain;
}
$domain = str_before($domain, '/');
return strtolower($domain);
}
protected function retrieveRawDnsRecords(string $domain): string
{
try {
return collect([
'A',
'AAAA',
'NS',
'SOA',
'MX',
'TXT',
'DNSKEY',
])
->map(function (string $recordType) use ($domain) {
$command = 'dig +nocmd ' . escapeshellarg($domain) . " {$recordType} +multiline +noall +answer";
$process = new Process($command);
$process->run();
if (!$process->isSuccessful()) {
throw new Exception('Dns records could not be fetched.');
}
return $process->getOutput();
})->implode('');
} catch (Exception $e) {
return '';
}
}
}

View file

@ -4,20 +4,3 @@ function locale()
{
return config('app.locale');
}
function formatOutput($input)
{
$collapseBracketInformation = '(((SOA|TXT|DNSKEY)[\s\w\.]+\())([\w\s\;\(\)\+\/\=]+)(\))';
$result = preg_replace("/$collapseBracketInformation/m", '$1 … $5', $input);
$replaceSpaces = '([ ]{2,}|[\t]+)';
$result = preg_replace("/$replaceSpaces/m", ' ', $result);
$replaceTrailingInformation = '^[\w\.]*\s[\d]+\s(IN\s)?';
$result = preg_replace("/$replaceTrailingInformation/m", '', $result);
$result = str_replace(PHP_EOL, ' | ', $result);
$result = trim($result, ' |');
return $result;
}

View file

@ -9,29 +9,28 @@
"license": "MIT",
"type": "project",
"require": {
"php": ">=7.3.0",
"bugsnag/bugsnag-laravel": "^2.0",
"php": ">=7.1.0",
"barryvdh/laravel-debugbar": "^2.4",
"bugsnag/bugsnag-laravel": "^2.6",
"doctrine/dbal": "^2.6",
"fideloper/proxy": "^4.0",
"fideloper/proxy": "~3.3",
"laracasts/flash": "^3.0",
"laravel/framework": "^6.0",
"laravel/slack-notification-channel": "^2.0",
"laravel/tinker": "^1.0",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
"pda/pheanstalk": "^3.1",
"predis/predis": "^1.1",
"spatie/dns": "^1.1.0",
"spatie/laravel-backup": "^6.0",
"spatie/laravel-backup": "^5.0",
"spatie/laravel-googletagmanager": "^2.4",
"spatie/laravel-http-logger": "^1.0",
"spatie/laravel-tail": "^3.0"
"spatie/laravel-tail": "^2.0"
},
"require-dev": {
"filp/whoops": "~2.0",
"friendsofphp/php-cs-fixer": "^2.4",
"fzaninotto/faker": "^1.4",
"fzaninotto/faker": "~1.4",
"laravel/envoy": "^1.3",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~8.0",
"nunomaduro/collision": "^3.0",
"facade/ignition": "^1.4"
"phpunit/phpunit": "~6.0"
},
"autoload": {
"classmap": [
@ -75,7 +74,7 @@
"sort-packages": true,
"optimize-autoloader": true,
"platform": {
"php": "7.3.1"
"php": "7.1"
}
},
"extra": {
@ -83,4 +82,4 @@
"dont-discover": []
}
}
}
}

3764
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -166,11 +166,10 @@ return [
/*
* Package Service Providers...
*/
Barryvdh\Debugbar\ServiceProvider::class,
Bugsnag\BugsnagLaravel\BugsnagServiceProvider::class,
Spatie\Backup\BackupServiceProvider::class,
Spatie\Tail\TailServiceProvider::class,
Bugsnag\BugsnagLaravel\BugsnagServiceProvider::class,
/*
* Application Service Providers...
@ -197,7 +196,6 @@ return [
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Arr' => Illuminate\Support\Arr::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
@ -229,11 +227,10 @@ return [
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'Str' => Illuminate\Support\Str::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Bugsnag' => Bugsnag\BugsnagLaravel\Facades\Bugsnag::class,
],
];

View file

@ -8,7 +8,7 @@ return [
* The name of this application. You can use this name to monitor
* the backups.
*/
'name' => env('APP_NAME', 'laravel-backup'),
'name' => env('APP_NAME'),
'source' => [
@ -18,7 +18,7 @@ return [
* The list of directories and files that will be included in the backup.
*/
'include' => [
base_path(),
//base_path(),
],
/*
@ -34,70 +34,32 @@ return [
/*
* Determines if symlinks should be followed.
*/
'follow_links' => false,
'followLinks' => false,
],
/*
* The names of the connections to the databases that should be backed up
* MySQL, PostgreSQL, SQLite and Mongo databases are supported.
*
* The content of the database dump may be customized for each connection
* by adding a 'dump' key to the connection settings in config/database.php.
* E.g.
* 'mysql' => [
* ...
* 'dump' => [
* 'excludeTables' => [
* 'table_to_exclude_from_backup',
* 'another_table_to_exclude'
* ]
* ]
* ],
*
* For a complete list of available customization options, see https://github.com/spatie/db-dumper
* Only MySQL and PostgreSQL databases are supported.
*/
'databases' => [
'mysql',
],
],
/*
* The database dump can be compressed to decrease diskspace usage.
*
* Out of the box Laravel-backup supplies
* Spatie\DbDumper\Compressors\GzipCompressor::class.
*
* You can also create custom compressor. More info on that here:
* https://github.com/spatie/db-dumper#using-compression
*
* If you do not want any compressor at all, set it to null.
*/
'database_dump_compressor' => null,
'destination' => [
/*
* The filename prefix used for the backup zip file.
*/
'filename_prefix' => '',
/*
* The disk names on which the backups will be stored.
*/
'disks' => [
'local',
'backups',
],
],
/*
* The directory where the temporary files will be stored.
*/
'temporary_directory' => storage_path('app/backup-temp'),
],
/*
* You can get notified when specific events occur. Out of the box you can use 'mail' and 'slack'.
* For Slack you need to install guzzlehttp/guzzle and laravel/slack-notification-channel.
* For Slack you need to install guzzlehttp/guzzle.
*
* You can also use your own notification classes, just make sure the class is named after one of
* the `Spatie\Backup\Events` classes.
@ -105,12 +67,12 @@ return [
'notifications' => [
'notifications' => [
\Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => ['slack'],
\Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['slac'],
\Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => ['slac'],
\Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => [],
\Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => [],
\Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => [],
\Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => ['slack'],
\Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['slack'],
\Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => ['slack'],
\Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => ['slack'],
\Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => [],
\Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => [],
],
/*
@ -120,21 +82,11 @@ return [
'notifiable' => \Spatie\Backup\Notifications\Notifiable::class,
'mail' => [
'to' => 'your@example.com',
'to' => 'freek@spatie.be',
],
'slack' => [
'webhook_url' => '',
/*
* If this is set to null the default channel of the webhook will be used.
*/
'channel' => null,
'username' => null,
'icon' => null,
'webhook_url' => env('SLACK_BACKUP_CHANNEL_WEBHOOK'),
],
],
@ -143,24 +95,20 @@ return [
* If a backup does not meet the specified requirements the
* UnHealthyBackupWasFound event will be fired.
*/
'monitor_backups' => [
'monitorBackups' => [
[
'name' => env('APP_NAME', 'laravel-backup'),
'disks' => ['local'],
'health_checks' => [
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1,
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000,
],
'name' => str_replace('https://', '', env('APP_URL')),
'disks' => ['backups'],
'newestBackupsShouldNotBeOlderThanDays' => 1,
'storageUsedMayNotBeHigherThanMegabytes' => 1000,
],
/*
[
'name' => 'name of the second app',
'disks' => ['local', 's3'],
'health_checks' => [
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1,
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000,
],
'newestBackupsShouldNotBeOlderThanDays' => 1,
'storageUsedMayNotBeHigherThanMegabytes' => 5000,
],
*/
],
@ -177,38 +125,38 @@ return [
*/
'strategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'default_strategy' => [
'defaultStrategy' => [
/*
* The number of days for which backups must be kept.
*/
'keep_all_backups_for_days' => 7,
'keepAllBackupsForDays' => 7,
/*
* The number of days for which daily backups must be kept.
*/
'keep_daily_backups_for_days' => 16,
'keepDailyBackupsForDays' => 16,
/*
* The number of weeks for which one weekly backup must be kept.
*/
'keep_weekly_backups_for_weeks' => 8,
'keepWeeklyBackupsForWeeks' => 8,
/*
* The number of months for which one monthly backup must be kept.
*/
'keep_monthly_backups_for_months' => 4,
'keepMonthlyBackupsForMonths' => 4,
/*
* The number of years for which one yearly backup must be kept.
*/
'keep_yearly_backups_for_years' => 2,
'keepYearlyBackupsForYears' => 2,
/*
* After cleaning up the backups remove the oldest backup until
* this amount of megabytes has been reached.
*/
'delete_oldest_backups_when_using_more_megabytes_than' => 5000,
'deleteOldestBackupsWhenUsingMoreMegabytesThan' => 5000,
],
],
];

View file

@ -36,8 +36,7 @@ return [
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
//
],
],

View file

@ -1,7 +1,5 @@
<?php
use Illuminate\Support\Str;
return [
/*
@ -13,8 +11,7 @@ return [
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file",
| "memcached", "redis", "dynamodb"
| Supported: "apc", "array", "database", "file", "memcached", "redis"
|
*/
@ -60,7 +57,7 @@ return [
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
@ -73,16 +70,7 @@ return [
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
'connection' => 'default',
],
],
@ -98,6 +86,6 @@ return [
|
*/
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
'prefix' => 'laravel',
];

View file

@ -1,7 +1,5 @@
<?php
use Illuminate\Support\Str;
return [
/*
@ -37,15 +35,12 @@ return [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
@ -55,17 +50,12 @@ return [
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
@ -73,14 +63,12 @@ return [
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
@ -88,7 +76,6 @@ return [
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
],
@ -112,34 +99,20 @@ return [
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'client' => 'predis',
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
'database' => 0,
],
],

View file

@ -37,7 +37,7 @@ return [
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3"
| Supported Drivers: "local", "ftp", "s3", "rackspace"
|
*/
@ -57,11 +57,10 @@ return [
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'key' => env('AWS_KEY'),
'secret' => env('AWS_SECRET'),
'region' => env('AWS_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],

View file

@ -1,52 +0,0 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Hash Driver
|--------------------------------------------------------------------------
|
| This option controls the default hash driver that will be used to hash
| passwords for your application. By default, the bcrypt algorithm is
| used; however, you remain free to modify this option if you wish.
|
| Supported: "bcrypt", "argon", "argon2id"
|
*/
'driver' => 'bcrypt',
/*
|--------------------------------------------------------------------------
| Bcrypt Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Bcrypt algorithm. This will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 10),
],
/*
|--------------------------------------------------------------------------
| Argon Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Argon algorithm. These will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'argon' => [
'memory' => 1024,
'threads' => 2,
'time' => 2,
],
];

View file

@ -1,94 +0,0 @@
<?php
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
'papertrail' => [
'driver' => 'monolog',
'level' => 'debug',
'handler' => SyslogUdpHandler::class,
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
],
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
],
],
];

View file

@ -11,8 +11,8 @@ return [
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "sendmail", "mailgun", "ses",
| "postmark", "log", "array"
| Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
| "sparkpost", "log", "array"
|
*/
@ -120,17 +120,4 @@ return [
],
],
/*
|--------------------------------------------------------------------------
| Log Channel
|--------------------------------------------------------------------------
|
| If you are using the "log" driver, you may specify the logging channel
| if you prefer to keep mail messages separate from other log entries
| for simpler reading. Otherwise, the default channel will be used.
|
*/
'log_channel' => env('MAIL_LOG_CHANNEL'),
];

View file

@ -4,16 +4,18 @@ return [
/*
|--------------------------------------------------------------------------
| Default Queue Connection Name
| Default Queue Driver
|--------------------------------------------------------------------------
|
| Laravel's queue API supports an assortment of back-ends via a single
| API, giving you convenient access to each back-end using the same
| syntax for every one. Here you may define a default connection.
| syntax for each one. Here you may set the default queue driver.
|
| Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'default' => env('QUEUE_CONNECTION', 'sync'),
'default' => env('QUEUE_DRIVER', 'sync'),
/*
|--------------------------------------------------------------------------
@ -24,8 +26,6 @@ return [
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'connections' => [
@ -46,24 +46,22 @@ return [
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'key' => 'your-public-key',
'secret' => 'your-secret-key',
'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id',
'queue' => 'your-queue-name',
'region' => 'us-east-1',
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'queue' => 'default',
'retry_after' => 90,
'block_for' => null,
],
],
@ -80,7 +78,6 @@ return [
*/
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],

View file

@ -8,26 +8,31 @@ return [
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Mailgun, Postmark, AWS and more. This file provides the de facto
| location for this type of information, allowing packages to have
| a conventional file to locate the various service credentials.
| as Stripe, Mailgun, SparkPost and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
],
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-east-1',
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],
'stripe' => [
'model' => App\Models\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
];

View file

@ -1,7 +1,5 @@
<?php
use Illuminate\Support\Str;
return [
/*
@ -14,7 +12,7 @@ return [
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "file", "cookie", "database", "apc",
| "memcached", "redis", "dynamodb", "array"
| "memcached", "redis", "array"
|
*/
@ -31,7 +29,7 @@ return [
|
*/
'lifetime' => env('SESSION_LIFETIME', 120),
'lifetime' => 120,
'expire_on_close' => false,
@ -72,7 +70,7 @@ return [
|
*/
'connection' => env('SESSION_CONNECTION', null),
'connection' => null,
/*
|--------------------------------------------------------------------------
@ -92,13 +90,13 @@ return [
| Session Cache Store
|--------------------------------------------------------------------------
|
| When using the "apc", "memcached", or "dynamodb" session drivers you may
| list a cache store that should be used for these sessions. This value
| must match with one of the application's configured cache "stores".
| When using the "apc" or "memcached" session drivers, you may specify a
| cache store that should be used for these sessions. This value must
| correspond with one of the application's configured cache stores.
|
*/
'store' => env('SESSION_STORE', null),
'store' => null,
/*
|--------------------------------------------------------------------------
@ -126,7 +124,7 @@ return [
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
str_slug(env('APP_NAME', 'laravel'), '_').'_session'
),
/*

View file

@ -28,9 +28,6 @@ return [
|
*/
'compiled' => env(
'VIEW_COMPILED_PATH',
realpath(storage_path('framework/views'))
),
'compiled' => realpath(storage_path('framework/views')),
];

View file

@ -1,5 +1,4 @@
<?php
use Illuminate\Support\Str;
/*
|--------------------------------------------------------------------------
@ -20,6 +19,6 @@ $factory->define(App\Models\User::class, function (Faker\Generator $faker) {
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => $password ?: $password = bcrypt('secret'),
'remember_token' => Str::random(10),
'remember_token' => str_random(10),
];
});

231
package-lock.json generated
View file

@ -332,13 +332,6 @@
"integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
"requires": {
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"async-each": {
@ -432,13 +425,6 @@
"private": "0.1.8",
"slash": "1.0.0",
"source-map": "0.5.7"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"babel-eslint": {
@ -471,11 +457,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
@ -509,13 +490,6 @@
"babel-runtime": "6.26.0",
"babel-types": "6.26.0",
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"babel-helper-explode-assignable-expression": {
@ -575,13 +549,6 @@
"babel-runtime": "6.26.0",
"babel-types": "6.26.0",
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"babel-helper-remap-async-to-generator": {
@ -730,13 +697,6 @@
"babel-traverse": "6.26.0",
"babel-types": "6.26.0",
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"babel-plugin-transform-es2015-classes": {
@ -1033,13 +993,6 @@
"lodash": "4.17.4",
"mkdirp": "0.5.1",
"source-map-support": "0.4.18"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"babel-runtime": {
@ -1061,13 +1014,6 @@
"babel-types": "6.26.0",
"babylon": "6.18.0",
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"babel-traverse": {
@ -1084,13 +1030,6 @@
"globals": "9.18.0",
"invariant": "2.2.2",
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"babel-types": {
@ -1102,13 +1041,6 @@
"esutils": "2.0.2",
"lodash": "4.17.4",
"to-fast-properties": "1.0.3"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"babylon": {
@ -3049,11 +2981,6 @@
"ms": "2.0.0"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@ -3644,8 +3571,7 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"optional": true
"bundled": true
},
"aproba": {
"version": "1.1.1",
@ -3688,8 +3614,7 @@
},
"balanced-match": {
"version": "0.4.2",
"bundled": true,
"optional": true
"bundled": true
},
"bcrypt-pbkdf": {
"version": "1.0.1",
@ -3702,7 +3627,6 @@
"block-stream": {
"version": "0.0.9",
"bundled": true,
"optional": true,
"requires": {
"inherits": "2.0.3"
}
@ -3710,7 +3634,6 @@
"boom": {
"version": "2.10.1",
"bundled": true,
"optional": true,
"requires": {
"hoek": "2.16.3"
}
@ -3718,7 +3641,6 @@
"brace-expansion": {
"version": "1.1.7",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "0.4.2",
"concat-map": "0.0.1"
@ -3726,8 +3648,7 @@
},
"buffer-shims": {
"version": "1.0.0",
"bundled": true,
"optional": true
"bundled": true
},
"caseless": {
"version": "0.12.0",
@ -3741,31 +3662,26 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"optional": true
"bundled": true
},
"combined-stream": {
"version": "1.0.5",
"bundled": true,
"optional": true,
"requires": {
"delayed-stream": "1.0.0"
}
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"optional": true
"bundled": true
},
"core-util-is": {
"version": "1.0.2",
"bundled": true,
"optional": true
"bundled": true
},
"cryptiles": {
"version": "2.0.5",
@ -3805,8 +3721,7 @@
},
"delayed-stream": {
"version": "1.0.0",
"bundled": true,
"optional": true
"bundled": true
},
"delegates": {
"version": "1.0.0",
@ -3828,8 +3743,7 @@
},
"extsprintf": {
"version": "1.0.2",
"bundled": true,
"optional": true
"bundled": true
},
"forever-agent": {
"version": "0.6.1",
@ -3848,13 +3762,11 @@
},
"fs.realpath": {
"version": "1.0.0",
"bundled": true,
"optional": true
"bundled": true
},
"fstream": {
"version": "1.0.11",
"bundled": true,
"optional": true,
"requires": {
"graceful-fs": "4.1.11",
"inherits": "2.0.3",
@ -3905,7 +3817,6 @@
"glob": {
"version": "7.1.2",
"bundled": true,
"optional": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
@ -3917,8 +3828,7 @@
},
"graceful-fs": {
"version": "4.1.11",
"bundled": true,
"optional": true
"bundled": true
},
"har-schema": {
"version": "1.0.5",
@ -3952,8 +3862,7 @@
},
"hoek": {
"version": "2.16.3",
"bundled": true,
"optional": true
"bundled": true
},
"http-signature": {
"version": "1.1.1",
@ -3968,7 +3877,6 @@
"inflight": {
"version": "1.0.6",
"bundled": true,
"optional": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
@ -3976,8 +3884,7 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true,
"optional": true
"bundled": true
},
"ini": {
"version": "1.3.4",
@ -3987,7 +3894,6 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "1.0.1"
}
@ -3999,8 +3905,7 @@
},
"isarray": {
"version": "1.0.0",
"bundled": true,
"optional": true
"bundled": true
},
"isstream": {
"version": "0.1.2",
@ -4063,13 +3968,11 @@
},
"mime-db": {
"version": "1.27.0",
"bundled": true,
"optional": true
"bundled": true
},
"mime-types": {
"version": "2.1.15",
"bundled": true,
"optional": true,
"requires": {
"mime-db": "1.27.0"
}
@ -4077,20 +3980,17 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true,
"optional": true
"bundled": true
},
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -4138,8 +4038,7 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"oauth-sign": {
"version": "0.8.2",
@ -4154,7 +4053,6 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1.0.2"
}
@ -4180,8 +4078,7 @@
},
"path-is-absolute": {
"version": "1.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"performance-now": {
"version": "0.2.0",
@ -4190,8 +4087,7 @@
},
"process-nextick-args": {
"version": "1.0.7",
"bundled": true,
"optional": true
"bundled": true
},
"punycode": {
"version": "1.4.1",
@ -4224,7 +4120,6 @@
"readable-stream": {
"version": "2.2.9",
"bundled": true,
"optional": true,
"requires": {
"buffer-shims": "1.0.0",
"core-util-is": "1.0.2",
@ -4267,15 +4162,13 @@
"rimraf": {
"version": "2.6.1",
"bundled": true,
"optional": true,
"requires": {
"glob": "7.1.2"
}
},
"safe-buffer": {
"version": "5.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"semver": {
"version": "5.3.0",
@ -4326,7 +4219,6 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
@ -4336,7 +4228,6 @@
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "5.0.1"
}
@ -4349,7 +4240,6 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "2.1.1"
}
@ -4362,7 +4252,6 @@
"tar": {
"version": "2.2.1",
"bundled": true,
"optional": true,
"requires": {
"block-stream": "0.0.9",
"fstream": "1.0.11",
@ -4412,8 +4301,7 @@
},
"util-deprecate": {
"version": "1.0.2",
"bundled": true,
"optional": true
"bundled": true
},
"uuid": {
"version": "3.0.1",
@ -4438,8 +4326,7 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true,
"optional": true
"bundled": true
}
}
},
@ -4668,13 +4555,6 @@
"glob": "7.1.2",
"lodash": "4.17.4",
"minimatch": "3.0.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"glogg": {
@ -5113,11 +4993,6 @@
"requires": {
"is-extglob": "2.1.1"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
@ -5354,11 +5229,6 @@
"supports-color": "4.5.0"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@ -6350,11 +6220,6 @@
"strip-bom": "3.0.0"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"os-locale": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
@ -6509,9 +6374,9 @@
}
},
"lodash": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"lodash._arraycopy": {
"version": "3.0.0",
@ -8663,11 +8528,6 @@
"is-extglob": "2.1.1"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"postcss": {
"version": "5.2.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
@ -8732,13 +8592,6 @@
"lodash": "4.17.4",
"postcss": "6.0.13",
"postcss-value-parser": "3.3.0"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"postcss-font-variant": {
@ -9487,11 +9340,6 @@
"supports-color": "4.5.0"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"log-symbols": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.1.0.tgz",
@ -10407,13 +10255,6 @@
"lodash": "4.17.4",
"scss-tokenizer": "0.2.3",
"yargs": "7.1.0"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"sass-loader": {
@ -11139,11 +10980,6 @@
}
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"log-symbols": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.1.0.tgz",
@ -11290,11 +11126,6 @@
"supports-color": "4.5.0"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"supports-color": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
@ -11865,11 +11696,6 @@
"requires": {
"ms": "2.0.0"
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
@ -12311,13 +12137,6 @@
"integrity": "sha1-atciI7PguDflMeRZfBmfkJNhUR4=",
"requires": {
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"webpack-notifier": {

View file

@ -18,7 +18,7 @@
"eslint-config-spatie": "^2.0.1",
"jest": "^20.0.4",
"laravel-mix": "^1.4",
"lodash": "^4.17.19",
"lodash": "^4.17.4",
"postcss-cli": "^4.1.0",
"postcss-cssnext": "^3.0.2",
"postcss-easy-import": "^2.1.0",

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="tests/bootstrap.php"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
@ -9,13 +9,13 @@
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
@ -23,16 +23,9 @@
</whitelist>
</filter>
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="APP_CONFIG_CACHE" value="bootstrap/cache/config.phpunit.php"/>
<server name="APP_SERVICES_CACHE" value="bootstrap/cache/services.phpunit.php"/>
<server name="APP_PACKAGES_CACHE" value="bootstrap/cache/packages.phpunit.php"/>
<server name="APP_ROUTES_CACHE" value="bootstrap/cache/routes.phpunit.php"/>
<server name="APP_EVENTS_CACHE" value="bootstrap/cache/events.phpunit.php"/>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
</phpunit>

View file

@ -1,5 +1,6 @@
h1 {
font-size: 1rem;
padding-top: 2rem;
}
.h1__prefix {

15
resources/assets/css/base/html.css vendored Normal file
View file

@ -0,0 +1,15 @@
html {
box-sizing: border-box;
height: 100%;
background-color: var(--gray-dark);
color: var(--gray-light);
font-weight: 400;
font-size: 16px;
font-family: 'Fira Mono', monospace;
line-height: 2;
/* 16px up to 1066, then grow */
@media (min-width: 1066px) {
font-size: 1.5vw;
}
}

View file

@ -3,8 +3,7 @@
flex-direction: column;
padding: 0 var(--gutter);
min-height: 100%;
background-color: var(--gray-dark);
color: var(--gray-light);
user-select: none;
/* Fade out overflow content on the right */
&:after {
@ -16,12 +15,4 @@
background-image: linear-gradient(to right, color(var(--gray-dark) a(0)), var(--gray-dark));
content: '';
}
&.-error {
background-color: var(--blue-bright);
&:after {
background-image: linear-gradient(to right, color(var(--blue-bright) a(0)), var(--blue-bright));
}
}
}

View file

@ -6,4 +6,5 @@
/* Give the pre a width and some room to scroll horizontally */
display: inline-block;
padding-right: var(--gutter);
user-select: text;
}

View file

@ -0,0 +1,3 @@
.title {
font-weight: 700;
}

View file

@ -5,5 +5,4 @@
--red: #8c251d;
--green: #6dc53c;
--yellow: #d9d771;
--blue-bright: #00F;
}

49
resources/assets/js/History.js vendored Normal file
View file

@ -0,0 +1,49 @@
class History {
constructor() {
this.importFromLocalStorage();
this.index = 0;
}
add(value) {
if (this.items.length > 1000) {
this.items.pop();
}
this.items.unshift(value);
this.save();
}
importFromLocalStorage() {
const storedHistory = JSON.parse(localStorage.getItem('history'));
this.items = storedHistory || [];
}
save() {
localStorage.setItem('history', JSON.stringify(this.items));
}
getPrevious() {
if (this.index < this.items.length - 1) {
return this.items[this.index++];
}
return this.items[this.items.length - 1];
}
getNext() {
if (this.index > 0) {
return this.items[--this.index];
}
return '';
}
clear() {
this.items = [];
this.save();
}
}
export default History;

View file

@ -1,17 +1,24 @@
const form = document.getElementById('form');
const input = document.getElementById('url');
require('./bootstrap');
const Vue = require('vue');
form.addEventListener('submit', event => {
event.preventDefault();
Vue.component('terminal', require('./components/terminal.vue'));
form.action = window.location.origin + '/' + input.value;
form.submit();
const app = new Vue({
el: '#main',
});
const input = document.getElementById('url');
window.addEventListener('click', event => {
event.stopPropagation();
const source = event.srcElement || event.originalTarget;
if (source.id !== 'results') {
input.focus();
}
setTimeout(() => {
if (! isResultTextSelected()) {
input.focus();

13
resources/assets/js/bootstrap.js vendored Normal file
View file

@ -0,0 +1,13 @@
/** Configuration of Axios for Laravel */
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
const token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
window.axios.defaults.headers.common['Accept'] = 'application/json';
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

View file

@ -0,0 +1,119 @@
<template>
<div>
<h1
v-if="results.length == 0"
class="title">
<span class="carret">~</span>
dnsrecords.io
</h1>
<div
v-for="result in results">
<h1
v-if="result.type == 'command'"
class="title">
<span class="carret">~</span>
dnsrecords.io $ {{ result.message }}
</h1>
<pre
v-else-if="result.type == 'default'"
class="main__results"
id="results"
v-html="result.message"
></pre>
<p
v-else-if="result.type == 'danger'"
class="alert alert--danger"
v-html="result.message"
></p>
<div
v-else=""
:class="'alert alert--' + result.type"
role="alert"
v-html="result.message"
></div>
</div>
<span class="carret -green">&rarr;</span>
<input
id="url"
name="command"
placeholder="Enter a domain"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
autofocus="autofocus"
spellcheck="false"
v-model="input"
v-on:keyup.enter="execute()"
v-on:keydown.up="previous()"
v-on:keydown.down="next()"
/>
</div>
</template>
<script>
import History from '../History.js';
export default {
updated() {
window.scrollTo(0, document.body.scrollHeight);
},
mounted() {
let hash = window.location.hash;
if ('' !== hash) {
this.input = hash.substr(1);
this.execute();
}
},
data() {
return {
results: [],
input: '',
history: new History()
}
},
methods : {
send(command) {
axios.get('/' + command).then(response => {
this.results.push(response.data);
})
},
previous() {
this.input = this.history.getPrevious();
},
next() {
this.input = this.history.getNext();
},
execute() {
let input = this.input;
this.input = '';
this.history.add(input);
this.results.push({
'message' : input,
'type': 'command',
});
window.location.hash = '#'+input;
switch(input)
{
case 'doom':
window.location.href = "https://js-dos.com/games/doom.exe.html";
return;
case 'clear':
return this.results = [];
case 'history -c':
return this.history.clear();
default:
this.send(input);
}
}
}
}
</script>

View file

@ -1,48 +0,0 @@
html {
box-sizing: border-box;
height: 100%;
font-weight: 400;
font-size: 16px;
font-family: 'Fira Mono', monospace;
line-height: 2;
@media (min-width: 1134px) {
font-size: 17px;
}
@media (min-width: 1200px) {
font-size: 18px;
}
@media (min-width: 1333px) {
font-size: 20px;
}
@media (min-width: 1466px) {
font-size: 22px;
}
@media (min-width: 1600px) {
font-size: 24px;
}
@media (min-width: 1733px) {
font-size: 26px;
}
@media (min-width: 1866px) {
font-size: 28px;
}
@media (min-width: 2000px) {
font-size: 30px;
}
@media (min-width: 2133px) {
font-size: 32px;
}
@media (min-width: 2400px) {
font-size: 36px;
}
}

View file

@ -1,7 +0,0 @@
.bookmarklet {
padding: 0 .5rem;
border-radius: 9999px;
background: color(var(--gray-light) a(.35));
color: var(--gray-dark);
white-space: nowrap;
}

View file

@ -1,11 +0,0 @@
.title {
font-weight: 700;
&.-error {
display: inline-block;
margin-bottom: 2rem;
padding: 0 .5rem;
background-color: var(--gray-light);
color: var(--blue-bright);
}
}

View file

@ -13,6 +13,7 @@ return [
|
*/
'password' => 'Passwords must be at least six characters and match the confirmation.',
'reset' => 'Your password has been reset!',
'sent' => 'We have e-mailed your password reset link!',
'token' => 'This password reset token is invalid.',

View file

@ -13,109 +13,80 @@ return [
|
*/
'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute may only contain letters.',
'alpha_dash' => 'The :attribute may only contain letters, numbers, dashes and underscores.',
'alpha_num' => 'The :attribute may only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
'between' => [
'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute may only contain letters.',
'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.',
'alpha_num' => 'The :attribute may only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
'between' => [
'numeric' => 'The :attribute must be between :min and :max.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'The :attribute must be between :min and :max characters.',
'array' => 'The :attribute must have between :min and :max items.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'The :attribute must be between :min and :max characters.',
'array' => 'The :attribute must have between :min and :max items.',
],
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'date' => 'The :attribute is not a valid date.',
'date_equals' => 'The :attribute must be a date equal to :date.',
'date_format' => 'The :attribute does not match the format :format.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'digits_between' => 'The :attribute must be between :min and :max digits.',
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'email' => 'The :attribute must be a valid email address.',
'ends_with' => 'The :attribute must end with one of the following: :values',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'gt' => [
'numeric' => 'The :attribute must be greater than :value.',
'file' => 'The :attribute must be greater than :value kilobytes.',
'string' => 'The :attribute must be greater than :value characters.',
'array' => 'The :attribute must have more than :value items.',
],
'gte' => [
'numeric' => 'The :attribute must be greater than or equal :value.',
'file' => 'The :attribute must be greater than or equal :value kilobytes.',
'string' => 'The :attribute must be greater than or equal :value characters.',
'array' => 'The :attribute must have :value items or more.',
],
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'lt' => [
'numeric' => 'The :attribute must be less than :value.',
'file' => 'The :attribute must be less than :value kilobytes.',
'string' => 'The :attribute must be less than :value characters.',
'array' => 'The :attribute must have less than :value items.',
],
'lte' => [
'numeric' => 'The :attribute must be less than or equal :value.',
'file' => 'The :attribute must be less than or equal :value kilobytes.',
'string' => 'The :attribute must be less than or equal :value characters.',
'array' => 'The :attribute must not have more than :value items.',
],
'max' => [
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'date' => 'The :attribute is not a valid date.',
'date_format' => 'The :attribute does not match the format :format.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'digits_between' => 'The :attribute must be between :min and :max digits.',
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'email' => 'The :attribute must be a valid email address.',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'max' => [
'numeric' => 'The :attribute may not be greater than :max.',
'file' => 'The :attribute may not be greater than :max kilobytes.',
'string' => 'The :attribute may not be greater than :max characters.',
'array' => 'The :attribute may not have more than :max items.',
'file' => 'The :attribute may not be greater than :max kilobytes.',
'string' => 'The :attribute may not be greater than :max characters.',
'array' => 'The :attribute may not have more than :max items.',
],
'mimes' => 'The :attribute must be a file of type: :values.',
'mimetypes' => 'The :attribute must be a file of type: :values.',
'min' => [
'mimes' => 'The :attribute must be a file of type: :values.',
'mimetypes' => 'The :attribute must be a file of type: :values.',
'min' => [
'numeric' => 'The :attribute must be at least :min.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
],
'not_in' => 'The selected :attribute is invalid.',
'not_regex' => 'The :attribute format is invalid.',
'numeric' => 'The :attribute must be a number.',
'present' => 'The :attribute field must be present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values are present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'not_in' => 'The selected :attribute is invalid.',
'numeric' => 'The :attribute must be a number.',
'present' => 'The :attribute field must be present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values is present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'same' => 'The :attribute and :other must match.',
'size' => [
'same' => 'The :attribute and :other must match.',
'size' => [
'numeric' => 'The :attribute must be :size.',
'file' => 'The :attribute must be :size kilobytes.',
'string' => 'The :attribute must be :size characters.',
'array' => 'The :attribute must contain :size items.',
'file' => 'The :attribute must be :size kilobytes.',
'string' => 'The :attribute must be :size characters.',
'array' => 'The :attribute must contain :size items.',
],
'starts_with' => 'The :attribute must start with one of the following: :values',
'string' => 'The :attribute must be a string.',
'timezone' => 'The :attribute must be a valid zone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'url' => 'The :attribute format is invalid.',
'uuid' => 'The :attribute must be a valid UUID.',
'string' => 'The :attribute must be a string.',
'timezone' => 'The :attribute must be a valid zone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'url' => 'The :attribute format is invalid.',
/*
|--------------------------------------------------------------------------
@ -139,9 +110,9 @@ return [
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap our attribute placeholder
| with something more reader friendly such as "E-Mail Address" instead
| of "email". This simply helps us make our message more expressive.
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/

View file

@ -1,5 +0,0 @@
@extends('errors::layout')
@section('title', 'Forbidden')
@section('message', 'You don\'t have the rights to do this.')

View file

@ -1,5 +0,0 @@
@extends('errors::layout')
@section('title', 'Page Not Found')
@section('message', 'The page you are looking for could not be found.')

View file

@ -1,5 +0,0 @@
@extends('errors::layout')
@section('title', 'Method not allowed')
@section('message', 'I\'m sorry, I was not built to do stuff like this.')

View file

@ -1,5 +0,0 @@
@extends('errors::layout')
@section('title', 'Page Expired')
@section('message', 'The page has expired due to inactivity. Please refresh and try again.')

View file

@ -1,5 +0,0 @@
@extends('errors::layout')
@section('title', 'Error')
@section('message', 'Too many requests.')

View file

@ -1,5 +0,0 @@
@extends('errors::layout')
@section('title', 'Error')
@section('message', 'Looks like something went wrong. Try again later.')

View file

@ -1,5 +0,0 @@
@extends('errors::layout')
@section('title', 'Service Unavailable')
@section('message', 'Be right back.')

View file

@ -1,33 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover">
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<title>@yield('title') ~ dnsrecords.io</title>
<link href="https://fonts.googleapis.com/css?family=Fira+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" href="{{ mix('/css/app.css') }}">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#151d21">
<meta name="theme-color" content="#ffffff">
</head>
<body class="layout -error">
<header class="header">
<h1 class="title -error">
<a href="https://dnsrecords.io">dnsrecords.io</a>
</h1>
</header>
<main class="main">
<pre class="main__results">@yield('message')</pre>
</main>
</body>
</html>

View file

@ -1,45 +1,12 @@
@extends('layout.master')
@section('content')
<header class="header">
<h1 class="title">
<span class="carret">~</span>
dnsrecords.io
</h1>
</header>
<main class="main">
@if(isset($output))
<pre class="main__results">{{ $output }}</pre>
@endif
@if($errors->has('input'))
<p id="results" class="alert alert--danger">
{{ $errors->first('input') }}
</p>
@endif
@include('layout._partials.flash')
<form id="form" method="post" action="/">
{{ csrf_field() }}
<span class="carret -green">&rarr;</span>
<input
id="url"
name="command"
placeholder="Enter a domain"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
autofocus="autofocus"
spellcheck="false"
/>
</form>
<main id="main" class="main">
<terminal></terminal>
</main>
<footer class="footer">
© <a href='https://spatie.be/en/opensource'>spatie</a> {{ date('Y') }} type '<kbd>help</kbd>'
© <a href='https://spatie.be/en/opensource'>spatie</a> {{ date('Y') }} stuck? type '<kbd>help</kbd>'
</footer>
@endsection

View file

@ -1,10 +0,0 @@
@foreach (session('flash_notification', collect())->toArray() as $message)
<div class="alert alert--{{ $message['level'] }}
{{ $message['important'] ? 'alert--important' : '' }}"
role="alert"
>
{!! $message['message'] !!}
</div>
@endforeach
{{ session()->forget('flash_notification') }}

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
@ -7,8 +7,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover">
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<title>{{ isset($domain) ? $domain . ' DNS records' : 'DNS records lookup' }} ~ dnsrecords.io</title>
<meta name="description" content="{{ isset($output) ? formatOutput($output) : 'DNS record lookups just as you like \'em' }}" />
<title>DNS records lookup ~ dnsrecords.io</title>
<meta name="description" content="DNS record lookups just as you like 'em" />
<link href="https://fonts.googleapis.com/css?family=Fira+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" href="{{ mix('/css/app.css') }}">
@ -19,7 +19,8 @@
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#151d21">
<meta name="theme-color" content="#151d21">
<meta name="theme-color" content="#ffffff">
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body class="layout">

View file

@ -1,9 +1,4 @@
<?php
Route::get('/', 'HomeController@index')->name('home');
Route::middleware(['sanitizeCommand', 'logRequest'])->group(function () {
Route::post('/', 'HomeController@submit');
Route::match(['get', 'post'], '/{command}', 'HomeController@submit')->where('command', '.+');
});
Route::match(['get', 'post'], '/{command}', 'HomeController@submit')->middleware('logRequest');

View file

@ -1,16 +0,0 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ClearTest extends TestCase
{
/** @test */
public function it_clears_the_output()
{
$this
->sendCommand('clear', '/spatie.be')
->assertRedirect('/');
}
}

View file

@ -1,70 +0,0 @@
<?php
namespace Test\Feature;
use Tests\TestCase;
class DnsLookupTest extends TestCase
{
/** @test */
public function it_can_lookup_a_normal_domain()
{
$this
->sendCommand('spatie.be')
->assertSee('<pre class="main__results">');
}
/** @test */
public function it_doesnt_fail_with_a_dot_as_search_query()
{
$this
->sendCommand('.')
->assertSuccessful();
$this
->post('/', ['command' => '.'])
->assertSee('root-servers.net');
}
/** @test */
public function it_redirects_to_home_when_the_domain_lookup_is_invalid()
{
$this->withoutExceptionHandling();
$this
->sendCommand('..')
->assertRedirect('/');
$this
->sendCommand('?')
->assertRedirect('/');
}
/** @test */
public function it_sanitizes_the_domain_lookup_when_it_has_a_scheme()
{
$this
->sendCommand('http://spatie.be')
->assertRedirect('/spatie.be');
$this
->sendCommand('https://spatie.be')
->assertRedirect('/spatie.be');
}
/** @test */
public function it_sanitizes_the_domain_lookup_when_it_has_a_path()
{
$this
->sendCommand('https://spatie.be/en/vacancies')
->assertRedirect('/spatie.be');
}
/** @test */
public function it_filters_out_html()
{
$this
->sendCommand('<iframe>')
->assertRedirect('/');
}
}

View file

@ -1,16 +0,0 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
class DoomTest extends TestCase
{
/** @test */
public function it_redirects_to_doom()
{
$this
->sendCommand('doom')
->assertRedirect('https://js-dos.com/games/doom.exe.html');
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}

View file

@ -1,18 +0,0 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
class IpTest extends TestCase
{
/** @test */
public function it_shows_your_ip_address()
{
$content = $this->sendCommand('ip')->content();
$isIpAddress = '/(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])/';
$this->assertRegExp($isIpAddress, $content);
}
}

View file

@ -1,22 +0,0 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ManualTest extends TestCase
{
/** @test */
public function it_shows_the_manual()
{
$this->sendCommand('help');
$flashMessage = $this->getFlashMessage();
$this->assertStringContainsString('domain name', $flashMessage);
$this->assertStringContainsString('ip', $flashMessage);
$this->assertStringContainsString('clear', $flashMessage);
$this->assertStringContainsString('doom', $flashMessage);
$this->assertStringContainsString('bookmarklet', $flashMessage);
}
}

View file

@ -3,26 +3,8 @@
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Foundation\Testing\TestResponse;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
protected $baseUrl = 'https://dnsrecords.io.dev';
protected function sendCommand(string $command, string $url = null): TestResponse
{
$url = $url ? $this->baseUrl . $url : "{$this->baseUrl}/{$command}";
return $this->post($url, compact('command'));
}
protected function getFlashMessage(): ?string
{
$flash = app('session.store')
->get('flash_notification');
return $flash ? $flash->first()->message : null;
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Tests\Unit;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$this->assertTrue(true);
}
}

View file

@ -1,29 +0,0 @@
<?php
use Illuminate\Contracts\Console\Kernel;
require_once __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Bootstrap The Test Environment
|--------------------------------------------------------------------------
|
| You may specify console commands that execute once before your test is
| run. You are free to add your own additional commands or logic into
| this file as needed in order to help your test suite run quicker.
|
*/
$commands = [
'config:cache',
'event:cache',
];
$app = require __DIR__.'/../bootstrap/app.php';
$console = tap($app->make(Kernel::class))->bootstrap();
foreach ($commands as $command) {
$console->call($command);
}

5
webpack.mix.js vendored
View file

@ -1,5 +1,6 @@
const mix = require('laravel-mix');
mix.config.uglify.compress.drop_console = false;
mix.config.postCss = require('./postcss.config').plugins;
/*
@ -15,5 +16,5 @@ mix.config.postCss = require('./postcss.config').plugins;
mix
.version()
.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css');
.js('resources/assets/js/app.js', 'public/js')
.postCss('resources/assets/css/app.css', 'public/css');

6413
yarn.lock

File diff suppressed because it is too large Load diff