Skip to content

Commit

Permalink
Feature/recaptcha (#165)
Browse files Browse the repository at this point in the history
* Created a config for the credentials

* Created a recaptcha-enabled submit button component

* Created a validation rule

* Added recaptcha to the contact form and login form

* Update resources/views/components/recaptcha-submit.blade.php

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Updated recaptcha rule

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
l-alexandrov and coderabbitai[bot] committed Apr 29, 2024
1 parent a238196 commit ff2a9c2
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 8 deletions.
14 changes: 13 additions & 1 deletion app/Http/Controllers/Auth/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@

namespace App\Http\Controllers\Auth;

use App\Rules\Recaptcha;
use Illuminate\Http\Request;
use Wave\Http\Controllers\Auth\LoginController as AuthLoginController;

class LoginController extends AuthLoginController
{

protected function validateLogin(Request $request)
{
$request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
'g-recaptcha-response' => [
'required',
new Recaptcha(),
]
]);
}
}
7 changes: 6 additions & 1 deletion app/Http/Requests/SendEmailRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Requests;

use App\Rules\Recaptcha;
use Illuminate\Foundation\Http\FormRequest;

class SendEmailRequest extends FormRequest
Expand All @@ -12,9 +13,13 @@ class SendEmailRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
return [
'g-recaptcha-response'=> [
'required',
new Recaptcha(),
],
'name' => [
'required',
'string',
Expand Down
26 changes: 26 additions & 0 deletions app/Rules/Recaptcha.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class Recaptcha implements ValidationRule
{
/**
* Run the validation rule.
*
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$g_response = \Http::asForm()->post('https://www.google.com/recaptcha/api/siteverify', [
'secret' => config('recaptcha.api_secret_key'),
'response' => $value,
'remoteip' => request()?->getClientIp(),
]);
if (!$g_response->json('success')) {
$fail("The {$attribute} is invalid.");
}
}
}
26 changes: 26 additions & 0 deletions app/View/Components/RecaptchaSubmit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\View\Components;

use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;

class RecaptchaSubmit extends Component
{
/**
* Create a new component instance.
*/
public function __construct(public string $action, public string $formId)
{
//
}

/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.recaptcha-submit');
}
}
24 changes: 24 additions & 0 deletions config/recaptcha.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);

/**
* To configure correctly please visit https://developers.google.com/recaptcha/docs/start
*/
return [

/**
*
* The site key
* get site key @ www.google.com/recaptcha/admin
*
*/
'api_site_key' => env('RECAPTCHA_SITE_KEY', ''),

/**
*
* The secret key
* get secret key @ www.google.com/recaptcha/admin
*
*/
'api_secret_key' => env('RECAPTCHA_SECRET_KEY', ''),
];
25 changes: 25 additions & 0 deletions resources/views/components/recaptcha-submit.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<button data-sitekey="{{ config('recaptcha.api_site_key') }}"
data-callback='onSubmit'
data-action='{{ $action }}'
{{ $attributes->merge(['class' => 'g-recaptcha']) }}
>
{{ $slot }}
</button>
@section('javascript')
<script>
let form = document.getElementById("{{ $formId }}");
function onSubmit(token) {
// Check form validity and submit if valid
if(form.checkValidity()){
form.submit();
} else {
// If not valid, create a temporary submit button to trigger form validation
// Create the temporary button, click and remove it
let tmpSubmit = document.createElement('button')
form.appendChild(tmpSubmit)
tmpSubmit.click()
form.removeChild(tmpSubmit)
}
}
</script>
@endsection
6 changes: 3 additions & 3 deletions resources/views/themes/bimbala/auth/login.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div class="px-4 py-8 bg-white border shadow border-gray-50 sm:rounded-lg sm:px-10">
<form action="#" method="POST">
<form action="#" method="POST" id="login-form">
@csrf
<div>

Expand Down Expand Up @@ -85,9 +85,9 @@

<div class="mt-6">
<span class="block w-full rounded-md shadow-sm">
<button type="submit" class="flex justify-center w-full px-4 py-2 text-sm font-medium text-white transition duration-150 ease-in-out border border-transparent rounded-md bg-wave-600 hover:bg-wave-500 focus:outline-none focus:border-wave-700 focus:shadow-outline-wave active:bg-wave-700">
<x-recaptcha-submit formId="login-form" action="login" class="flex justify-center w-full px-4 py-2 text-sm font-medium text-white transition duration-150 ease-in-out border border-transparent rounded-md bg-wave-600 hover:bg-wave-500 focus:outline-none focus:border-wave-700 focus:shadow-outline-wave active:bg-wave-700">
Sign in
</button>
</x-recaptcha-submit>
</span>
</div>
</form>
Expand Down
8 changes: 5 additions & 3 deletions resources/views/themes/bimbala/contact.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
<div class="grid grid-cols-6 sm:grid-cols-12 bg-white">
<div class="w-full border border-gray-200 shadow-sm col-span-6 sm:col-span-8 p-5">
<form
class="flex flex-col justify-center items-center my-auto h-full p-10 grid grid-cols-1 sm:grid-cols-2 gap-6 relative" action="{{ route('contact-send') }}" method="POST">
class="flex flex-col justify-center items-center my-auto h-full p-10 grid grid-cols-1 sm:grid-cols-2 gap-6 relative" action="{{ route('contact-send') }}" method="POST"
id="contact-form"
>
@if(session('success'))
<p class="col-span-1 sm:col-span-2 p-1 bg-green-600 text-white rounded-full text-center">{{session('success')}}</p>
@endif
Expand Down Expand Up @@ -118,11 +120,11 @@ class="flex flex-col justify-center items-center my-auto h-full p-10 grid grid-c
</label>
@csrf
<div class="block sm:col-start-2 text-right absolute bottom-5 right-7">
<button type="submit" class="rounded-full bg-purple-700 text-white hover:bg-purple-900 p-3">
<x-recaptcha-submit class="rounded-full bg-purple-700 text-white hover:bg-purple-900 p-3" formId="contact-form" action="contact">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 rotate-45 -skew-y-[15deg]" viewBox="0 0 20 20" fill="currentColor">
<path d="M10.894 2.553a1 1 0 00-1.788 0l-7 14a1 1 0 001.169 1.409l5-1.429A1 1 0 009 15.571V11a1 1 0 112 0v4.571a1 1 0 00.725.962l5 1.428a1 1 0 001.17-1.408l-7-14z" />
</svg>
</button>
</x-recaptcha-submit>
</div>
</form>
</div>
Expand Down
1 change: 1 addition & 0 deletions resources/views/themes/bimbala/partials/footer.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@

<!-- Scripts -->
<script src="{{ mix('js/app.js', 'themes/' . $theme->folder) }}" defer></script>
<script src="https://www.google.com/recaptcha/api.js" defer async></script>

@yield('javascript')

Expand Down

0 comments on commit ff2a9c2

Please sign in to comment.