siwwy :3 #3
					 12 changed files with 329 additions and 91 deletions
				
			
		feat: add guestbook with rate limiting (#6)
* Re-add guestbook w/ rate limiting * Add guestbook to navbar
				commit
				
					
					
						8482a98ca6
					
				
			
		
							
								
								
									
										29
									
								
								app/Http/Controllers/GuestbookController.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Http/Controllers/GuestbookController.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use DB;
 | 
			
		||||
 | 
			
		||||
class GuestbookController extends Controller {
 | 
			
		||||
    public function guestbook() {
 | 
			
		||||
        return view('pages.guestbook');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function guestbookPost(Request $request) {
 | 
			
		||||
        $this->validate($request, [
 | 
			
		||||
            'name' => 'required',
 | 
			
		||||
            'message' => 'required'
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        DB::insert('INSERT INTO guestbook_entries (name, timestamp, ip_address, agent, message) values (?, ?, ?, ?, ?)', array(
 | 
			
		||||
            htmlspecialchars($request->get('name')),
 | 
			
		||||
            time(),
 | 
			
		||||
            $request->ip(),
 | 
			
		||||
            $request->userAgent(),
 | 
			
		||||
            htmlspecialchars($request->get('message'))
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
        return back()->with('success', 'Entry submitted successfully!');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +45,11 @@ class Kernel extends HttpKernel
 | 
			
		|||
        ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    protected $routeMiddleware = [
 | 
			
		||||
        'rate_limit' => \App\Http\Middleware\RateLimiter::class,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The application's middleware aliases.
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								app/Http/Middleware/RateLimiter.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/Http/Middleware/RateLimiter.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Middleware;
 | 
			
		||||
 | 
			
		||||
use Closure;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
 | 
			
		||||
class RateLimiter
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle an incoming request.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
 | 
			
		||||
     */
 | 
			
		||||
    public function handle(Request $request, Closure $next): Response
 | 
			
		||||
    {
 | 
			
		||||
        $ipAddress = $request->ip();
 | 
			
		||||
        $cacheKey = 'rate_limit_' . $ipAddress;
 | 
			
		||||
 | 
			
		||||
        if (Cache::has($cacheKey)) {
 | 
			
		||||
            // If the cache key exists, the IP has submitted an entry within the last hour
 | 
			
		||||
            return response()->view('errors.ratelimit-guestbook', [], 429);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Add the IP address to the cache and set the expiration time to one hour
 | 
			
		||||
        Cache::put($cacheKey, true, 60);
 | 
			
		||||
 | 
			
		||||
        return $next($request);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +9,8 @@
 | 
			
		|||
        "guzzlehttp/guzzle": "^7.2",
 | 
			
		||||
        "laravel/framework": "^10.10",
 | 
			
		||||
        "laravel/sanctum": "^3.2",
 | 
			
		||||
        "laravel/tinker": "^2.8"
 | 
			
		||||
        "laravel/tinker": "^2.8",
 | 
			
		||||
        "spatie/laravel-honeypot": "^4.3"
 | 
			
		||||
    },
 | 
			
		||||
    "require-dev": {
 | 
			
		||||
        "fakerphp/faker": "^1.9.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										138
									
								
								composer.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										138
									
								
								composer.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
			
		||||
        "This file is @generated automatically"
 | 
			
		||||
    ],
 | 
			
		||||
    "content-hash": "aa322c53454393ed775cfe4807d54a50",
 | 
			
		||||
    "content-hash": "505f8d503188864625fc855900ea2202",
 | 
			
		||||
    "packages": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "brick/math",
 | 
			
		||||
| 
						 | 
				
			
			@ -2994,6 +2994,142 @@
 | 
			
		|||
            ],
 | 
			
		||||
            "time": "2023-04-15T23:01:58+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "spatie/laravel-honeypot",
 | 
			
		||||
            "version": "4.3.2",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/spatie/laravel-honeypot.git",
 | 
			
		||||
                "reference": "eab92dd2096f1cdb83c28ced4f4632d3cfde2872"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/spatie/laravel-honeypot/zipball/eab92dd2096f1cdb83c28ced4f4632d3cfde2872",
 | 
			
		||||
                "reference": "eab92dd2096f1cdb83c28ced4f4632d3cfde2872",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "illuminate/contracts": "^8.0|^9.0|^10.0",
 | 
			
		||||
                "illuminate/encryption": "^8.0|^9.0|^10.0",
 | 
			
		||||
                "illuminate/http": "^8.0|^9.0|^10.0",
 | 
			
		||||
                "illuminate/support": "^8.0|^9.0|^10.0",
 | 
			
		||||
                "illuminate/validation": "^8.0|^9.0|^10.0",
 | 
			
		||||
                "nesbot/carbon": "^2.0",
 | 
			
		||||
                "php": "^8.0",
 | 
			
		||||
                "spatie/laravel-package-tools": "^1.9",
 | 
			
		||||
                "symfony/http-foundation": "^5.1.2|^6.0"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "livewire/livewire": "^2.10",
 | 
			
		||||
                "orchestra/testbench": "^6.23|^7.0|^8.0",
 | 
			
		||||
                "pestphp/pest-plugin-livewire": "^1.0",
 | 
			
		||||
                "phpunit/phpunit": "^9.4",
 | 
			
		||||
                "spatie/pest-plugin-snapshots": "^1.1",
 | 
			
		||||
                "spatie/phpunit-snapshot-assertions": "^4.2",
 | 
			
		||||
                "spatie/test-time": "^1.2.1"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "extra": {
 | 
			
		||||
                "laravel": {
 | 
			
		||||
                    "providers": [
 | 
			
		||||
                        "Spatie\\Honeypot\\HoneypotServiceProvider"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "Spatie\\Honeypot\\": "src"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Freek Van der Herten",
 | 
			
		||||
                    "email": "freek@spatie.be",
 | 
			
		||||
                    "homepage": "https://spatie.be",
 | 
			
		||||
                    "role": "Developer"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Preventing spam submitted through forms",
 | 
			
		||||
            "homepage": "https://github.com/spatie/laravel-honeypot",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "laravel-honeypot",
 | 
			
		||||
                "spatie"
 | 
			
		||||
            ],
 | 
			
		||||
            "support": {
 | 
			
		||||
                "source": "https://github.com/spatie/laravel-honeypot/tree/4.3.2"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": [
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://spatie.be/open-source/support-us",
 | 
			
		||||
                    "type": "custom"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2023-01-17T07:09:34+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "spatie/laravel-package-tools",
 | 
			
		||||
            "version": "1.15.0",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/spatie/laravel-package-tools.git",
 | 
			
		||||
                "reference": "efab1844b8826443135201c4443690f032c3d533"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/efab1844b8826443135201c4443690f032c3d533",
 | 
			
		||||
                "reference": "efab1844b8826443135201c4443690f032c3d533",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "illuminate/contracts": "^9.28|^10.0",
 | 
			
		||||
                "php": "^8.0"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "mockery/mockery": "^1.5",
 | 
			
		||||
                "orchestra/testbench": "^7.7|^8.0",
 | 
			
		||||
                "pestphp/pest": "^1.22",
 | 
			
		||||
                "phpunit/phpunit": "^9.5.24",
 | 
			
		||||
                "spatie/pest-plugin-test-time": "^1.1"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "Spatie\\LaravelPackageTools\\": "src"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Freek Van der Herten",
 | 
			
		||||
                    "email": "freek@spatie.be",
 | 
			
		||||
                    "role": "Developer"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Tools for creating Laravel packages",
 | 
			
		||||
            "homepage": "https://github.com/spatie/laravel-package-tools",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "laravel-package-tools",
 | 
			
		||||
                "spatie"
 | 
			
		||||
            ],
 | 
			
		||||
            "support": {
 | 
			
		||||
                "issues": "https://github.com/spatie/laravel-package-tools/issues",
 | 
			
		||||
                "source": "https://github.com/spatie/laravel-package-tools/tree/1.15.0"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": [
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://github.com/spatie",
 | 
			
		||||
                    "type": "github"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2023-04-27T08:09:01+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "symfony/console",
 | 
			
		||||
            "version": "v6.3.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,15 +34,6 @@
 | 
			
		|||
    */
 | 
			
		||||
 | 
			
		||||
    'connections' => [
 | 
			
		||||
 | 
			
		||||
        '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'),
 | 
			
		||||
| 
						 | 
				
			
			@ -62,37 +53,6 @@
 | 
			
		|||
                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'),
 | 
			
		||||
            'username' => env('DB_USERNAME', 'forge'),
 | 
			
		||||
            'password' => env('DB_PASSWORD', ''),
 | 
			
		||||
            'charset' => 'utf8',
 | 
			
		||||
            'prefix' => '',
 | 
			
		||||
            'prefix_indexes' => true,
 | 
			
		||||
            'search_path' => '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'),
 | 
			
		||||
            'username' => env('DB_USERNAME', 'forge'),
 | 
			
		||||
            'password' => env('DB_PASSWORD', ''),
 | 
			
		||||
            'charset' => 'utf8',
 | 
			
		||||
            'prefix' => '',
 | 
			
		||||
            'prefix_indexes' => true,
 | 
			
		||||
            // 'encrypt' => env('DB_ENCRYPT', 'yes'),
 | 
			
		||||
            // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
| 
						 | 
				
			
			@ -107,45 +67,4 @@
 | 
			
		|||
    */
 | 
			
		||||
 | 
			
		||||
    'migrations' => 'migrations',
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    |--------------------------------------------------------------------------
 | 
			
		||||
    | Redis Databases
 | 
			
		||||
    |--------------------------------------------------------------------------
 | 
			
		||||
    |
 | 
			
		||||
    | 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
 | 
			
		||||
    | 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_'),
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        'default' => [
 | 
			
		||||
            'url' => env('REDIS_URL'),
 | 
			
		||||
            'host' => env('REDIS_HOST', '127.0.0.1'),
 | 
			
		||||
            'username' => env('REDIS_USERNAME'),
 | 
			
		||||
            'password' => env('REDIS_PASSWORD'),
 | 
			
		||||
            'port' => env('REDIS_PORT', '6379'),
 | 
			
		||||
            'database' => env('REDIS_DB', '0'),
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        'cache' => [
 | 
			
		||||
            'url' => env('REDIS_URL'),
 | 
			
		||||
            'host' => env('REDIS_HOST', '127.0.0.1'),
 | 
			
		||||
            'username' => env('REDIS_USERNAME'),
 | 
			
		||||
            'password' => env('REDIS_PASSWORD'),
 | 
			
		||||
            'port' => env('REDIS_PORT', '6379'),
 | 
			
		||||
            'database' => env('REDIS_CACHE_DB', '1'),
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,6 +115,10 @@ div.preview pre.small, div.project pre.small {
 | 
			
		|||
div.preview pre, div.project pre {
 | 
			
		||||
    background-color: #222;
 | 
			
		||||
    color: #ccc;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    padding: 0.2em;
 | 
			
		||||
    max-width: 90%
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.project pre {
 | 
			
		||||
| 
						 | 
				
			
			@ -283,13 +287,6 @@ .header {
 | 
			
		|||
    color: #FFFFFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.preview pre, div.project pre {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    padding: 0.2em;
 | 
			
		||||
    max-width: 90%
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 { font-size: 150% }
 | 
			
		||||
h2 { font-size: 130% }
 | 
			
		||||
h3 { font-size: 115% }
 | 
			
		||||
| 
						 | 
				
			
			@ -324,3 +321,32 @@ a {
 | 
			
		|||
    color: #99f;
 | 
			
		||||
    text-decoration: none
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.gb_entryform tr td {
 | 
			
		||||
    border: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.gb_entryform tr td label {
 | 
			
		||||
    padding-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.gb_entryform tr td span.text-danger {
 | 
			
		||||
    padding-left: 5px;
 | 
			
		||||
    color: rgb(255, 114, 114);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.gb_entryform tr td textarea,
 | 
			
		||||
table.gb_entryform tr td input {
 | 
			
		||||
    margin-bottom: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.gb_entry tr td {
 | 
			
		||||
    border: solid #FFFFFF;
 | 
			
		||||
    width: 500px;
 | 
			
		||||
    vertical-align: top;
 | 
			
		||||
    padding: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.gb_entry {
 | 
			
		||||
    margin-bottom: 5px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								public/css/minimal.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								public/css/minimal.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
html {
 | 
			
		||||
    color-scheme: dark;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
    font-family: sans-serif;
 | 
			
		||||
    margin: 0px;
 | 
			
		||||
    margin-left: 10px;
 | 
			
		||||
    color: #ddd;
 | 
			
		||||
    background-color: #333;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								resources/views/errors/ratelimit-guestbook.blade.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								resources/views/errors/ratelimit-guestbook.blade.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <title>Error 429: Overclocking Detected!</title>
 | 
			
		||||
    <link rel="stylesheet" href="{{ URL::asset ('css/minimal.css') }}"/>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
    <h1>Error 429: Overclocking Detected!</h1>
 | 
			
		||||
    <hr/>
 | 
			
		||||
    <p>Whoa there! Your submissions are going at warp speed.</p>
 | 
			
		||||
    <p>Remember you can only submit an entry <u>once every hour</u>!</p>
 | 
			
		||||
    <br/>
 | 
			
		||||
    Click <a href="/guestbook">here</a> to go back to the guestbook.
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
            <a href="/projects/">projects</a> |
 | 
			
		||||
            <a href="/calculators/">calculators</a> |
 | 
			
		||||
            <a href="/computers/">computers</a> |
 | 
			
		||||
            <a href="/bookmarks/">bookmarks</a>
 | 
			
		||||
            <a href="/bookmarks/">bookmarks</a> |
 | 
			
		||||
            <a href="/guestbook/">guestbook</a>
 | 
			
		||||
        </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										53
									
								
								resources/views/pages/guestbook.blade.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								resources/views/pages/guestbook.blade.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
@extends('layouts.default')
 | 
			
		||||
@section('title', 'guestbook')
 | 
			
		||||
@section('content')
 | 
			
		||||
    <br/>
 | 
			
		||||
    <form method="POST" action="/guestbook">
 | 
			
		||||
        @csrf
 | 
			
		||||
        <x-honeypot />
 | 
			
		||||
        <table class="gb_entryform">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <label for="name">Name:</label>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input name="name" type="text" id="name" placeholder="John Doe">
 | 
			
		||||
                </td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <span class="text-danger">{{ $errors->first('name') }}</span>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <label for="message">Message:</label>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <textarea name="message" id="message" rows="3"></textarea>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <span class="text-danger">{{ $errors->first('message') }}</span>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td colspan="2">
 | 
			
		||||
                    <button type="submit">Submit</button>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </table>
 | 
			
		||||
    </form>
 | 
			
		||||
    <p>You can submit an entry <u>once every hour</u>.</p>
 | 
			
		||||
    <p>Your IP address <u>will</u> be logged but <u>will not</u> be publically displayed.</p>
 | 
			
		||||
    <hr/>
 | 
			
		||||
    @php
 | 
			
		||||
        $entries = DB::select('SELECT name, timestamp, message FROM guestbook_entries ORDER BY id DESC');
 | 
			
		||||
    @endphp
 | 
			
		||||
    <h1>Entries <small>({{ count($entries) }} total)</small></h1>
 | 
			
		||||
    @foreach ($entries as $entry)
 | 
			
		||||
        <table class="gb_entry"><tr><td>
 | 
			
		||||
            Name: {{ $entry->name }}<br/>
 | 
			
		||||
            Date: {{ gmdate("H:i:s - Y-m-d", $entry->timestamp) }}<br/><br/>
 | 
			
		||||
            {{ htmlspecialchars($entry->message) }}
 | 
			
		||||
        </td></tr></table>
 | 
			
		||||
    @endforeach
 | 
			
		||||
@stop
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -32,3 +32,12 @@
 | 
			
		|||
Route::get('/computers', function () {
 | 
			
		||||
    return View::make('pages.computers');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
Route::get('/guestbook', 'App\Http\Controllers\GuestbookController@guestbook')
 | 
			
		||||
    ->name('guestbook');
 | 
			
		||||
 | 
			
		||||
Route::post('/guestbook', 'App\Http\Controllers\GuestbookController@guestbookpost')
 | 
			
		||||
    ->name('guestbookPost')
 | 
			
		||||
    ->middleware('rate_limit');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue