Updated functionality such as: registration, registration verification by email and password change by email

This commit is contained in:
ygbanzato 2023-04-22 10:12:00 +01:00
parent 3343150b7e
commit 7f4defa009
16 changed files with 810 additions and 20 deletions

View File

@ -8,6 +8,8 @@
use Illuminate\Validation\Rule;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Illuminate\Auth\Events\Registered;
class CreateNewUser implements CreatesNewUsers
{
use PasswordValidationRules;
@ -36,5 +38,7 @@ public function create(array $input): User
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
// event(new Registered($user));
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Laravel\Fortify\Contracts\SendPasswordResetLinkViewResponse;
class PasswordResetLinkController extends Controller
{
public function create()
{
return view('auth.forgot-password');
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
class ResetPasswordController extends Controller
{
// public function create(Request $request, $token)
// {
// return view('auth.reset-password', ['token' => $token, 'email' => $request->email]);
// }
public function reset(Request $request)
{
$request->validate([
'token' => 'required',
'email' => 'required|email',
'password' => 'required|min:8|confirmed',
]);
$response = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user, $password) {
$user->forceFill([
'password' => bcrypt($password)
])->save();
$user->setRememberToken(Str::random(60));
}
);
if ($response == Password::PASSWORD_RESET) {
return response()->json(['message' => 'Password reset successfully.']);
} else {
return response()->json(['message' => 'Failed to reset the password.'], 400);
}
}
}
// use App\Http\Controllers\ResetPasswordController;
// Route::post('/reset-password', [ResetPasswordController::class, 'reset'])->name('password.update');

View File

@ -8,7 +8,11 @@
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
use Illuminate\Contracts\Auth\MustVerifyEmail;
class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable;

View File

@ -10,6 +10,13 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Laravel\Fortify\Contracts\ResetPasswordViewResponse;
use App\Http\Controllers\Auth\ResetPasswordController;
use App\Http\Controllers\Auth\PasswordResetLinkController;
use Laravel\Fortify\Fortify;
class FortifyServiceProvider extends ServiceProvider
@ -19,7 +26,9 @@ class FortifyServiceProvider extends ServiceProvider
*/
public function register(): void
{
//
$this->app->singleton(ResetPasswordController::class, function () {
return new ResetPasswordController();
});
}
/**
@ -32,11 +41,21 @@ public function boot(): void
return view('auth.login');
});
Fortify::registerView(function () {
return view('auth.register');
});
Fortify::verifyEmailView(function () {
return view('auth.verify-email');
});
Fortify::createUsersUsing(CreateNewUser::class);
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
RateLimiter::for('login', function (Request $request) {
$email = (string) $request->email;
@ -47,5 +66,30 @@ public function boot(): void
RateLimiter::for('two-factor', function (Request $request) {
return Limit::perMinute(5)->by($request->session()->get('login.id'));
});
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
Fortify::requestPasswordResetLinkView(function () {
return view('auth.forgot-password');
});
$this->registerPasswordResetResponseBindings();
Fortify::resetPasswordView(function ($request) {
return view('auth.reset-password', ['token' => $request->route('token')]);
});
}
protected function registerPasswordResetResponseBindings()
{
$this->app->singleton(SendPasswordResetLinkViewResponse::class, function () {
return view('auth.forgot-password');
});
$this->app->singleton(ResetPasswordViewResponse::class, function () {
return view('auth.reset-password');
});
}
}

View File

@ -6,11 +6,13 @@
"license": "MIT",
"require": {
"php": "^8.1",
"guzzlehttp/guzzle": "^7.2",
"guzzlehttp/guzzle": "^7.5",
"laravel/fortify": "^1.17",
"laravel/framework": "^10.8",
"laravel/sanctum": "^3.2",
"laravel/tinker": "^2.8"
"laravel/tinker": "^2.8",
"symfony/http-client": "^6.2",
"symfony/mailgun-mailer": "^6.2"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",

236
composer.lock generated
View File

@ -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": "245aaa8f3ba6d74abbfa93a3545386ff",
"content-hash": "c5af53907d38feda2d66777d4dc85856",
"packages": [
{
"name": "bacon/bacon-qr-code",
@ -3747,6 +3747,175 @@
],
"time": "2023-02-16T09:57:23+00:00"
},
{
"name": "symfony/http-client",
"version": "v6.2.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
"reference": "7daf5d24c21a683164688b95bb73b7a4bd3b32fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/7daf5d24c21a683164688b95bb73b7a4bd3b32fc",
"reference": "7daf5d24c21a683164688b95bb73b7a4bd3b32fc",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/log": "^1|^2|^3",
"symfony/deprecation-contracts": "^2.1|^3",
"symfony/http-client-contracts": "^3",
"symfony/service-contracts": "^1.0|^2|^3"
},
"provide": {
"php-http/async-client-implementation": "*",
"php-http/client-implementation": "*",
"psr/http-client-implementation": "1.0",
"symfony/http-client-implementation": "3.0"
},
"require-dev": {
"amphp/amp": "^2.5",
"amphp/http-client": "^4.2.1",
"amphp/http-tunnel": "^1.0",
"amphp/socket": "^1.1",
"guzzlehttp/promises": "^1.4",
"nyholm/psr7": "^1.0",
"php-http/httplug": "^1.0|^2.0",
"psr/http-client": "^1.0",
"symfony/dependency-injection": "^5.4|^6.0",
"symfony/http-kernel": "^5.4|^6.0",
"symfony/process": "^5.4|^6.0",
"symfony/stopwatch": "^5.4|^6.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\HttpClient\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
"homepage": "https://symfony.com",
"keywords": [
"http"
],
"support": {
"source": "https://github.com/symfony/http-client/tree/v6.2.9"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-04-11T16:03:19+00:00"
},
{
"name": "symfony/http-client-contracts",
"version": "v3.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client-contracts.git",
"reference": "df2ecd6cb70e73c1080e6478aea85f5f4da2c48b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/df2ecd6cb70e73c1080e6478aea85f5f4da2c48b",
"reference": "df2ecd6cb70e73c1080e6478aea85f5f4da2c48b",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"suggest": {
"symfony/http-client-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.3-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
"Symfony\\Contracts\\HttpClient\\": ""
},
"exclude-from-classmap": [
"/Test/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Generic abstractions related to HTTP clients",
"homepage": "https://symfony.com",
"keywords": [
"abstractions",
"contracts",
"decoupling",
"interfaces",
"interoperability",
"standards"
],
"support": {
"source": "https://github.com/symfony/http-client-contracts/tree/v3.2.1"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-03-01T10:32:47+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v6.2.8",
@ -4015,6 +4184,71 @@
],
"time": "2023-03-14T15:00:05+00:00"
},
{
"name": "symfony/mailgun-mailer",
"version": "v6.2.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailgun-mailer.git",
"reference": "9e27b8ec2f6ee7575c6229a61be1578a5a4b21ee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/9e27b8ec2f6ee7575c6229a61be1578a5a4b21ee",
"reference": "9e27b8ec2f6ee7575c6229a61be1578a5a4b21ee",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/mailer": "^5.4.21|^6.2.7"
},
"require-dev": {
"symfony/http-client": "^5.4|^6.0"
},
"type": "symfony-mailer-bridge",
"autoload": {
"psr-4": {
"Symfony\\Component\\Mailer\\Bridge\\Mailgun\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Mailgun Mailer Bridge",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/mailgun-mailer/tree/v6.2.7"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-02-21T10:35:38+00:00"
},
{
"name": "symfony/mime",
"version": "v6.2.7",

View File

@ -83,7 +83,9 @@
|
*/
'locale' => 'en',
// 'locale' => 'en',
'locale' => 'pt',
/*
|--------------------------------------------------------------------------
@ -170,7 +172,9 @@
App\Providers\RouteServiceProvider::class,
// Laravel\Fortify\FortifyServiceProvider::class,
App\Providers\FortifyServiceProvider::class
App\Providers\FortifyServiceProvider::class,
])->toArray(),
/*

View File

@ -134,8 +134,8 @@
'features' => [
Features::registration(),
Features::resetPasswords(),
Features::emailVerification(),
// Features::emailVerification(),
// Features::updateProfileInformation(),
// Features::updatePasswords(),
// Features::twoFactorAuthentication([
@ -144,9 +144,4 @@
// // 'window' => 0,
// ]),
],
];

View File

@ -51,6 +51,8 @@
'mailgun' => [
'transport' => 'mailgun',
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
// 'client' => [
// 'timeout' => 5,
// ],

View File

@ -0,0 +1,178 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => 'O campo :attribute deve ser aceito.',
'active_url' => 'O campo :attribute não é uma URL válida.',
'after' => 'O campo :attribute deve ser uma data posterior a :date.',
'after_or_equal' => 'O campo :attribute deve ser uma data superior ou igual a :date.',
'alpha' => 'O campo :attribute deve ser apenas letras.',
'alpha_dash' => 'O campo :attribute só pode conter letras, números e traços.',
'alpha_num' => 'O campo :attribute só pode conter letras e números.',
'array' => 'O campo :attribute deve conter um array.',
'before' => 'O campo :attribute deve conter uma data anterior a :date.',
'before_or_equal' => 'O campo :attribute deve conter uma data inferior ou igual a :date.',
'between' => [
'numeric' => 'O campo :attribute deve conter um número entre :min e :max.',
'file' => 'O campo :attribute deve conter um arquivo de :min a :max kilobytes.',
'string' => 'O campo :attribute deve conter entre :min a :max caracteres.',
'array' => 'O campo :attribute deve conter de :min a :max itens.',
],
'boolean' => 'O campo :attribute deve conter o valor verdadeiro ou falso.',
'confirmed' => 'A confirmação para o campo :attribute não coincide.',
'date' => 'O campo :attribute não contém uma data válida.',
'date_format' => 'A data informada para o campo :attribute não respeita o formato :format.',
'different' => 'Os campos :attribute e :other devem conter valores diferentes.',
'digits' => 'O campo :attribute deve conter :digits dígitos.',
'digits_between' => 'O campo :attribute deve conter entre :min a :max dígitos.',
'dimensions' => 'O valor informado para o campo :attribute não é uma dimensão de imagem válida.',
'distinct' => 'O campo :attribute contém um valor duplicado.',
'email' => 'O campo :attribute não contém um endereço de email válido.',
'exists' => 'O valor selecionado para o campo :attribute é inválido.',
'file' => 'O campo :attribute deve conter um arquivo.',
'filled' => 'O campo :attribute é obrigatório.',
'gt' => [
'numeric' => 'O campo :attribute deve ser maior que :value.',
'file' => 'O campo :attribute deve ser maior que :value kilobytes.',
'string' => 'O campo :attribute deve ser maior que :value caracteres.',
'array' => 'O campo :attribute deve ter mais que :value items.',
],
'gte' => [
'numeric' => 'O campo :attribute deve ser maior ou igual a :value.',
'file' => 'O campo :attribute deve ser maior ou igual a :value kilobytes.',
'string' => 'O campo :attribute deve ser maior ou igual a :value caracteres.',
'array' => 'O campo :attribute deve ter :value items ou mais.',
],
'image' => 'O campo :attribute deve conter uma imagem.',
'in' => 'O campo :attribute não contém um valor válido.',
'in_array' => 'O campo :attribute não existe em :other.',
'integer' => 'O campo :attribute deve conter um número inteiro.',
'ip' => 'O campo :attribute deve conter um IP válido.',
'ipv4' => 'O campo :attribute deve conter um IPv4 válido.',
'ipv6' => 'O campo :attribute deve conter um IPv6 válido.',
'json' => 'O campo :attribute deve conter uma string JSON válida.',
'lt' => [
'numeric' => 'O campo :attribute deve ser menor que :value.',
'file' => 'O campo :attribute deve ser menor que :value kilobytes.',
'string' => 'O campo :attribute deve ser menor que :value caracteres.',
'array' => 'O campo :attribute deve ter menos do que :value items.',
],
'lte' => [
'numeric' => 'O campo :attribute deve ser menor ou igual a :value.',
'file' => 'O campo :attribute deve ser menor ou igual a :value kilobytes.',
'string' => 'O campo :attribute deve ser menor ou igual a :value caracteres.',
'array' => 'O campo :attribute não deve ter mais do que :value items.',
],
'max' => [
'numeric' => 'O campo :attribute não pode conter um valor superior a :max.',
'file' => 'O campo :attribute não pode conter um arquivo com mais de :max kilobytes.',
'string' => 'O campo :attribute não pode conter mais de :max caracteres.',
'array' => 'O campo :attribute deve conter no máximo :max itens.',
],
'mimes' => 'O campo :attribute deve conter um arquivo do tipo: :values.',
'mimetypes' => 'O campo :attribute deve conter um arquivo do tipo: :values.',
'min' => [
'numeric' => 'O campo :attribute deve conter um número superior ou igual a :min.',
'file' => 'O campo :attribute deve conter um arquivo com no mínimo :min kilobytes.',
'string' => 'O campo :attribute deve conter no mínimo :min caracteres.',
'array' => 'O campo :attribute deve conter no mínimo :min itens.',
],
'not_in' => 'O campo :attribute contém um valor inválido.',
'not_regex' => 'The :attribute format is invalid.',
'numeric' => 'O campo :attribute deve conter um valor numérico.',
'present' => 'O campo :attribute deve estar presente.',
'regex' => 'O formato do valor informado no campo :attribute é inválido.',
'required' => 'O campo :attribute é obrigatório.',
'required_if' => 'O campo :attribute é obrigatório quando o valor do campo :other é igual a :value.',
'required_unless' => 'O campo :attribute é obrigatório a menos que :other esteja presente em :values.',
'required_with' => 'O campo :attribute é obrigatório quando :values está presente.',
'required_with_all' => 'O campo :attribute é obrigatório quando um dos :values está presente.',
'required_without' => 'O campo :attribute é obrigatório quando :values não está presente.',
'required_without_all' => 'O campo :attribute é obrigatório quando nenhum dos :values está presente.',
'same' => 'Os campos :attribute e :other devem conter valores iguais.',
'size' => [
'numeric' => 'O campo :attribute deve conter o número :size.',
'file' => 'O campo :attribute deve conter um arquivo com o tamanho de :size kilobytes.',
'string' => 'O campo :attribute deve conter :size caracteres.',
'array' => 'O campo :attribute deve conter :size itens.',
],
'string' => 'O campo :attribute deve ser uma string.',
'timezone' => 'O campo :attribute deve conter um fuso horário válido.',
'unique' => 'O valor informado para o campo :attribute já está em uso.',
'uploaded' => 'Falha no Upload do arquivo :attribute.',
'url' => 'O formato da URL informada para o campo :attribute é inválido.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| 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.
|
*/
'attributes' => [
'address' => 'endereço',
'age' => 'idade',
'body' => 'conteúdo',
'city' => 'cidade',
'country' => 'país',
'date' => 'data',
'day' => 'dia',
'description' => 'descrição',
'excerpt' => 'resumo',
'first_name' => 'primeiro nome',
'gender' => 'gênero',
'hour' => 'hora',
'last_name' => 'sobrenome',
'message' => 'mensagem',
'minute' => 'minuto',
'mobile' => 'celular',
'month' => 'mês',
'name' => 'nome',
'password_confirmation' => 'confirmação da senha',
'password' => 'senha',
'senha' => 'Minimo de 8 Caracteres',
'phone' => 'telefone',
'second' => 'segundo',
'sex' => 'sexo',
'state' => 'estado',
'subject' => 'assunto',
'text' => 'texto',
'time' => 'hora',
'title' => 'título',
'username' => 'usuário',
'year' => 'ano',
],
];

View File

@ -0,0 +1,39 @@
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Reset Password') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('password.email') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Send Password Reset Link') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>

View File

@ -1 +1,40 @@
<h1>Teste de REgister</h1>
<!-- resources/views/auth/register.blade.php -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registro</title>
</head>
<body>
<h1>Registro</h1>
<form method="POST" action="{{ route('register') }}">
@csrf
<label for="name">Nome:</label>
<input type="text" id="name" name="name" required autofocus>
@error('name')
<p>{{ $message }}</p>
@enderror
<label for="email">E-mail:</label>
<input type="email" id="email" name="email" required>
@error('email')
<p>{{ $message }}</p>
@enderror
<label for="password">Senha:</label>
<input type="password" id="password" name="password" required>
@error('password')
<p>{{ $message }}</p>
@enderror
<label for="password_confirmation">Confirme sua senha:</label>
<input type="password" id="password_confirmation" name="password_confirmation" required>
<button type="submit">Registrar</button>
</form>
</body>
</html>

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ config('app.name', 'Laravel') }}</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Reset Password') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('password.update') }}">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<div class="form-group">
<label for="email">{{ __('E-Mail Address') }}</label>
<input id="email" type="email"
class="form-control @error('email') is-invalid @enderror" name="email"
value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="form-group">
<label for="password">{{ __('Password') }}</label>
<input id="password" type="password"
class="form-control @error('password') is-invalid @enderror" name="password"
required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="form-group">
<label for="password-confirm">{{ __('Confirm Password') }}</label>
<input id="password-confirm" type="password" class="form-control"
name="password_confirmation" required autocomplete="new-password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">
{{ __('Reset Password') }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="{{ asset('js/app.js') }}" defer></script>
</body>
</html>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ config('app.name', 'Laravel') }} - Verificar e-mail</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Verificar seu endereço de e-mail</div>
<div class="card-body">
@if (session('status') == 'verification-link-sent')
<div class="alert alert-success" role="alert">
Um novo link de verificação foi enviado para o endereço de e-mail fornecido durante o registro.
</div>
@endif
<p>Antes de prosseguir, verifique seu e-mail para obter o link de verificação. Se você não recebeu o e-mail, clique no botão abaixo para solicitar outro.</p>
<form method="POST" action="{{ route('verification.send') }}">
@csrf
<button type="submit" class="btn btn-primary">Reenviar link de verificação</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,6 +1,19 @@
<?php
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\ForgotPasswordController;
use App\Http\Controllers\Auth\ResetPasswordController;
use App\Http\Controllers\NewPasswordController;
use App\Http\Controllers\Auth\PasswordResetLinkController;
/*
|--------------------------------------------------------------------------
@ -13,7 +26,62 @@
|
*/
Route::middleware(['auth', 'verified'])->group(function () {
// Rotas protegidas que exigem verificação de e-mail
Route::get('/', function () {
return view('welcome');
})-> middleware('auth');
});
});
// Route::post('/reset-password', [ResetPasswordController::class, 'reset'])->name('password.update');
// Route::get('/forgot-password', [PasswordResetLinkController::class, 'create'])->middleware(['guest'])->name('password.request');
// Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
// $request->fulfill();
// return redirect('/');
// })->middleware(['auth', 'signed'])->name('verification.verify');
// Route::get('/email/verify', function () {
// return view('auth.verify-email');
// })->middleware('auth')->name('verification.notice');
// Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
// $request->fulfill();
// return redirect('/');
// })->middleware(['auth', 'signed'])->name('verification.verify');
// Route::post('/email/verification-notification', function (Request $request) {
// $request->user()->sendEmailVerificationNotification();
// return back()->with('status', 'verification-link-sent');
// })->middleware(['auth', 'throttle:6,1'])->name('verification.send');
// Route::get('/test-email', function () {
// $to = 'yumex180@gmail.com';
// $subject = 'Test Email from Laravel';
// $message = Mail::raw('This is a test email from Laravel.', function ($message) use ($to, $subject) {
// $message->to($to)->subject($subject);
// });
// if ($message) {
// return 'Email sent successfully';
// } else {
// return 'Failed to send email';
// }
// });
// Route::get('/forgot-password', [ForgotPasswordController::class, 'showLinkRequestForm'])->name('password.request');
// Route::post('/forgot-password', [ForgotPasswordController::class, 'sendResetLinkEmail'])->name('password.email');
// Route::get('/reset-password/{token}', [ResetPasswordController::class, 'showResetForm'])->name('password.reset');
// Route::post('/reset-password', [ResetPasswordController::class, 'reset'])->name('password.update')