Add app register email verify resends

pull/5814/head
Daniel Supernault 1 month ago
parent 6f0b64fdab
commit dbd1e17b25
No known key found for this signature in database
GPG Key ID: 23740873EE6F76A1

@ -59,12 +59,14 @@ class AppRegisterController extends Controller
'message' => 'Too many attempts, please try again later.',
]);
DB::rollBack();
return redirect()->away("pixelfed://verifyEmail?{$errorParams}");
}
$registration = AppRegister::create([
'email' => $email,
'verify_code' => $code,
'uses' => 1,
'email_delivered_at' => now(),
]);
@ -117,6 +119,82 @@ class AppRegisterController extends Controller
]);
}
public function resendVerification(Request $request)
{
abort_unless(config('auth.in_app_registration'), 404);
$open = (bool) config_cache('pixelfed.open_registration');
if (! $open || $request->user()) {
return redirect('/');
}
return view('auth.iar-resend');
}
public function resendVerificationStore(Request $request)
{
abort_unless(config('auth.in_app_registration'), 404);
$open = (bool) config_cache('pixelfed.open_registration');
if (! $open || $request->user()) {
return redirect('/');
}
$rules = [
'email' => 'required|email:rfc,dns,spoof,strict|unique:users,email|exists:app_registers,email',
];
if ((bool) config_cache('captcha.enabled') && (bool) config_cache('captcha.active.register')) {
$rules['h-captcha-response'] = 'required|captcha';
}
$this->validate($request, $rules);
$email = strtolower($request->input('email'));
$code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
DB::beginTransaction();
$exists = AppRegister::whereEmail($email)->first();
if (! $exists || $exists->uses > 5) {
$errorMessage = $exists->uses > 5 ? 'Too many attempts have been made, please contact the admins.' : 'Email not found';
$errorParams = http_build_query([
'status' => 'error',
'message' => $errorMessage,
]);
DB::rollBack();
return redirect()->away("pixelfed://verifyEmail?{$errorParams}");
}
$registration = $exists->update([
'verify_code' => $code,
'uses' => ($exists->uses + 1),
'email_delivered_at' => now(),
]);
try {
Mail::to($email)->send(new InAppRegisterEmailVerify($code));
} catch (\Exception $e) {
DB::rollBack();
$errorParams = http_build_query([
'status' => 'error',
'message' => 'Failed to send verification code',
]);
return redirect()->away("pixelfed://verifyEmail?{$errorParams}");
}
DB::commit();
$queryParams = http_build_query([
'email' => $request->email,
'expires_in' => 3600,
'status' => 'success',
]);
return redirect()->away("pixelfed://verifyEmail?{$queryParams}");
}
public function onboarding(Request $request)
{
abort_unless(config('auth.in_app_registration'), 404);
@ -161,7 +239,7 @@ class AppRegisterController extends Controller
'email_verified_at' => now(),
]);
sleep(random_int(5,10));
sleep(random_int(8, 10));
$user = User::findOrFail($user->id);
$token = $user->createToken('Pixelfed App', ['read', 'write', 'follow', 'push']);
$tokenModel = $token->token;

@ -98,6 +98,10 @@ class AppServiceProvider extends ServiceProvider
return Limit::perHour(10)->by($request->ip());
});
RateLimiter::for('app-code-resend', function (Request $request) {
return Limit::perHour(5)->by($request->ip());
});
// Model::preventLazyLoading(true);
}

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('app_registers', function (Blueprint $table) {
$table->unsignedInteger('uses')->default(0);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('app_registers', function (Blueprint $table) {
$table->dropColumn('uses');
});
}
};

@ -0,0 +1,145 @@
@extends('layouts.blank')
@section('content')
<div class="container">
<div class="row min-vh-100 align-items-center justify-content-center">
<div class="col-12 col-md-6 col-lg-5">
<div class="text-center mb-5">
<img src="/img/pixelfed-icon-white.svg" width="90">
</div>
<div class="card shadow-sm">
<div class="card-body p-4">
<h3 class="text-center">Resend Verification</h3>
<p class="lead text-center mb-4">Enter your email so we can send another verification code via email</p>
<form method="POST" action="/i/app-email-resend">
@csrf
<div class="form-group">
<label for="email">Email address</label>
<input type="email"
class="form-control @error('email') is-invalid @enderror"
id="email"
name="email"
required
autocomplete="email"
@if(request()->filled('email'))
value="{{rawurldecode(request()->input('email'))}}"
@endif
>
@error('email')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
@if((bool) config_cache('captcha.enabled') && (bool) config_cache('captcha.active.register'))
<div class="form-group text-center">
{!! Captcha::display() !!}
</div>
@endif
<button type="submit" class="btn btn-primary btn-block">
Send Verification Code
</button>
</form>
@if ($errors->any())
<div class="mt-4">
<p class="text-center">Click <a href="/i/app-email-verify">here</a> to send a new request.</p>
</div>
@endif
</div>
</div>
</div>
</div>
</div>
@endsection
@push('styles')
<style>
:root {
--bg-color: #111827;
--card-bg: #1f2937;
--text-color: #f3f4f6;
--text-muted: #9ca3af;
--input-bg: #374151;
--input-border: #4b5563;
--input-focus: #3b82f6;
--card-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.3);
}
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s, color 0.3s;
min-height: 100vh;
display: flex;
align-items: center;
}
.card {
background-color: var(--card-bg);
border: none;
border-radius: 1rem;
box-shadow: var(--card-shadow);
}
.benefits-list {
color: var(--text-muted);
}
.benefits-list i {
color: #3b82f6;
margin-right: 0.5rem;
}
.form-control {
background-color: var(--input-bg);
border-color: var(--input-border);
color: var(--text-color);
border-radius: 0.5rem;
padding: 0.75rem 1rem;
transition: all 0.2s;
}
.form-control:focus {
background-color: var(--input-bg);
border-color: var(--input-focus);
color: var(--text-color);
box-shadow: 0 0 0 0.2rem rgba(59, 130, 246, 0.25);
}
.btn-primary {
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
font-weight: 500;
transition: transform 0.2s;
background-color: #3b82f6;
border-color: #3b82f6;
}
.btn-primary:hover {
transform: translateY(-1px);
background-color: #2563eb;
border-color: #2563eb;
}
.form-group label {
font-weight: 500;
margin-bottom: 0.5rem;
}
@media (prefers-color-scheme: dark) {
a {
color: #60a5fa;
}
a:hover {
color: #93c5fd;
}
.card {
border: 1px solid rgba(255, 255, 255, 0.1);
}
}
</style>
@endpush

@ -13,16 +13,6 @@
<h2 class="text-center">Join Pixelfed</h2>
<p class="lead text-center mb-4">Enter Your Email</p>
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST">
@csrf
@ -32,6 +22,7 @@
class="form-control @error('email') is-invalid @enderror"
id="email"
name="email"
placeholder="Enter your email address here"
required
autocomplete="email">
@error('email')
@ -49,6 +40,12 @@
Send Verification Code
</button>
</form>
@if ($errors->any())
<div class="mt-4">
<p class="text-center">If you need to resend the email verification, click <a href="/i/app-email-resend">here</a>.</p>
</div>
@endif
</div>
</div>
</div>

@ -141,6 +141,8 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
Route::get('/i/app-email-verify', 'AppRegisterController@index');
Route::post('/i/app-email-verify', 'AppRegisterController@store')->middleware('throttle:app-signup');
Route::get('/i/app-email-resend', 'AppRegisterController@resendVerification');
Route::post('/i/app-email-resend', 'AppRegisterController@resendVerificationStore')->middleware('throttle:app-code-resend');
Route::group(['prefix' => 'i'], function () {
Route::redirect('/', '/');

Loading…
Cancel
Save