diff --git a/.env.example b/.env.example index 2a660eb..01431a9 100644 --- a/.env.example +++ b/.env.example @@ -3,24 +3,20 @@ APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=http://localhost:8000 - APP_LOCALE=en APP_FALLBACK_LOCALE=en APP_FAKER_LOCALE=en_US - APP_MAINTENANCE_DRIVER=file -# APP_MAINTENANCE_STORE=database +# --- Logging & Performance --- PHP_CLI_SERVER_WORKERS=4 - BCRYPT_ROUNDS=12 - LOG_CHANNEL=stack LOG_STACK=single LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug -# Database Configuration +# --- Database --- DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 @@ -28,34 +24,41 @@ DB_DATABASE=dy_app_db DB_USERNAME=root DB_PASSWORD= -# Session Configuration +# --- Session & Cache --- SESSION_DRIVER=database SESSION_LIFETIME=120 SESSION_ENCRYPT=false SESSION_PATH=/ SESSION_DOMAIN=null - -# Broadcasting & Filesystem -BROADCAST_CONNECTION=log +CACHE_STORE=database FILESYSTEM_DISK=local QUEUE_CONNECTION=database -# Cache Configuration -CACHE_STORE=database -# CACHE_PREFIX= - -# Memcached Configuration +# --- Memcached & Redis --- MEMCACHED_HOST=127.0.0.1 - -# Redis Configuration REDIS_CLIENT=phpredis REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 -# Mail Configuration +# --- Broadcasting (Reverb) --- +BROADCAST_CONNECTION=log +REVERB_APP_ID= +REVERB_APP_KEY= +REVERB_APP_SECRET= +REVERB_HOST="localhost" +REVERB_PORT=8080 +REVERB_SCHEME=http + +# --- Vite --- +VITE_APP_NAME="${APP_NAME}" +VITE_REVERB_APP_KEY="${REVERB_APP_KEY}" +VITE_REVERB_HOST="${REVERB_HOST}" +VITE_REVERB_PORT="${REVERB_PORT}" +VITE_REVERB_SCHEME="${REVERB_SCHEME}" + +# --- Mail Configuration --- MAIL_MAILER=smtp -# MAIL_SCHEME=null MAIL_HOST=127.0.0.1 MAIL_PORT=587 MAIL_USERNAME=null @@ -64,7 +67,7 @@ MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}" -# Support Mailer (Secondary) +# --- Support Mailer --- MAIL_SUPPORT_MAILER=smtp MAIL_SUPPORT_HOST=127.0.0.1 MAIL_SUPPORT_PORT=587 @@ -74,58 +77,43 @@ MAIL_SUPPORT_ENCRYPTION=tls MAIL_SUPPORT_FROM_ADDRESS="support@example.com" MAIL_SUPPORT_FROM_NAME="DyDev Support" -# AWS Configuration +# --- Services (AWS) --- AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= AWS_USE_PATH_STYLE_ENDPOINT=false -# VITE Configuration -VITE_APP_NAME="${APP_NAME}" - -# Social Authentication (OAuth) Configuration +# --- Social Authentication --- GITHUB_CLIENT_ID= GITHUB_CLIENT_SECRET= -GITHUB_REDIRECT_URI=${APP_URL}/auth/github/callback +GITHUB_REDIRECT_URI="${APP_URL}/auth/github/callback" GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= -GOOGLE_REDIRECT_URI=${APP_URL}/auth/google/callback +GOOGLE_REDIRECT_URI="${APP_URL}/auth/google/callback" -# CA ROOT +# --- Certificate Authority (CA) --- CA_ROOT_COUNTRY_NAME="ID" -CA_ROOT_ORGANIZATION_NAME="DyDev TrustLab OpenSource" +CA_ROOT_ORGANIZATION_NAME="DyDev TrustLab OpenSource" CA_ROOT_ORGANIZATIONAL_UNIT_NAME="www.dyzulk.com" CA_ROOT_COMMON_NAME="DyzulkDev" -# CA INTERMEDIATE 4096 CA_4096_COUNTRY_NAME="ID" -CA_4096_ORGANIZATION_NAME="DyDev TrustLab" +CA_4096_ORGANIZATION_NAME="DyDev TrustLab" CA_4096_ORGANIZATIONAL_UNIT_NAME="www.dyzulk.com" CA_4096_COMMON_NAME="DyDev Infinity CA1" -# CA INTERMEDIATE 2048 CA_2048_COUNTRY_NAME="ID" -CA_2048_ORGANIZATION_NAME="Twinpath TrustLab" +CA_2048_ORGANIZATION_NAME="Twinpath TrustLab" CA_2048_ORGANIZATIONAL_UNIT_NAME="www.dyzulk.com" CA_2048_COMMON_NAME="Twinpath Infinity CA2" -# CA LEAF DEFAULT CA_LEAF_DEFAULT_COUNTRY_NAME="ID" CA_LEAF_DEFAULT_LOCALITY="Jakarta" CA_LEAF_DEFAULT_STATE="DKI Jakarta" CA_LEAF_DEFAULT_ORGANIZATION_NAME="MyLab Secured" -# Reverb (WebSockets) -REVERB_APP_ID= -REVERB_APP_KEY= -REVERB_APP_SECRET= -REVERB_HOST="localhost" -REVERB_PORT=8080 -REVERB_SCHEME=http - -VITE_REVERB_APP_KEY="${REVERB_APP_KEY}" -VITE_REVERB_HOST="${REVERB_HOST}" -VITE_REVERB_PORT="${REVERB_PORT}" -VITE_REVERB_SCHEME="${REVERB_SCHEME}" +# --- Security (Turnstile) --- +TURNSTILE_SITE_KEY= +TURNSTILE_SECRET_KEY= diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 8a257e0..aecad60 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -22,7 +22,10 @@ class ForgotPasswordController extends Controller */ public function sendResetLinkEmail(Request $request) { - $request->validate(['email' => 'required|email']); + $request->validate([ + 'email' => 'required|email', + 'cf-turnstile-response' => ['required', new \App\Rules\Turnstile], + ]); // We will send the password reset link to this user. Once we have attempted // to send the link, we will examine the response then see the message we diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index a4062ac..14138f7 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -29,6 +29,7 @@ class AuthController extends Controller $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], + 'cf-turnstile-response' => ['required', new \App\Rules\Turnstile], ]); // Find user by email @@ -72,6 +73,7 @@ class AuthController extends Controller 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8', 'terms' => 'required|accepted', + 'cf-turnstile-response' => ['required', new \App\Rules\Turnstile], ]); $roleInfo = \App\Models\Role::where('name', 'customer')->first(); diff --git a/app/Http/Controllers/ContactController.php b/app/Http/Controllers/ContactController.php index 093ec5c..a9bd99c 100644 --- a/app/Http/Controllers/ContactController.php +++ b/app/Http/Controllers/ContactController.php @@ -20,6 +20,7 @@ class ContactController extends Controller 'category' => 'required|string|in:Legal Inquiry,Technical Support,Partnership,Other', 'subject' => 'required|string|max:255', 'message' => 'required|string|max:2000', + 'cf-turnstile-response' => ['required', new \App\Rules\Turnstile], ]); ContactSubmission::create([ diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 46fcb38..4da24be 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -33,7 +33,10 @@ class SearchController extends Controller if ($user->isAdmin()) { // 2. Admin: User Search - $users = User::where('name', 'like', "%$query%") + $users = User::where(function($q) use ($query) { + $q->where('first_name', 'like', "%$query%") + ->orWhere('last_name', 'like', "%$query%"); + }) ->orWhere('email', 'like', "%$query%") ->limit(5) ->get() diff --git a/app/Rules/Turnstile.php b/app/Rules/Turnstile.php new file mode 100644 index 0000000..43d3c3f --- /dev/null +++ b/app/Rules/Turnstile.php @@ -0,0 +1,28 @@ +post('https://challenges.cloudflare.com/turnstile/v0/siteverify', [ + 'secret' => env('TURNSTILE_SECRET_KEY'), + 'response' => $value, + 'remoteip' => request()->ip(), + ]); + + if (! $response->json('success')) { + $fail('The :attribute verification failed. Please try again.'); + } + } +} diff --git a/resources/views/components/turnstile.blade.php b/resources/views/components/turnstile.blade.php new file mode 100644 index 0000000..ba4be4a --- /dev/null +++ b/resources/views/components/turnstile.blade.php @@ -0,0 +1,11 @@ +@props(['theme' => 'auto', 'size' => 'normal', 'tabindex' => 0]) + + + +
diff --git a/resources/views/pages/auth/forgot-password.blade.php b/resources/views/pages/auth/forgot-password.blade.php index 1087c63..ecfac36 100644 --- a/resources/views/pages/auth/forgot-password.blade.php +++ b/resources/views/pages/auth/forgot-password.blade.php @@ -52,6 +52,8 @@ @enderror + +