Add AppRegister

This commit is contained in:
Daniel Supernault 2025-01-31 00:41:40 -07:00
parent 52f8363024
commit 604746bd5e
No known key found for this signature in database
GPG key ID: 23740873EE6F76A1
8 changed files with 243 additions and 0 deletions

View file

@ -0,0 +1,80 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\AppRegister;
use App\Mail\InAppRegisterEmailVerify;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
class AppRegisterController extends Controller
{
public function index(Request $request)
{
abort_unless(config('auth.iar') == true, 404);
// $open = (bool) config_cache('pixelfed.open_registration');
// if(!$open || $request->user()) {
if($request->user()) {
return redirect('/');
}
return view('auth.iar');
}
public function store(Request $request)
{
abort_unless(config('auth.iar') == true, 404);
$rules = [
'email' => 'required|email:rfc,dns,spoof,strict|unique:users,email|unique: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 = $request->input('email');
$code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
$exists = AppRegister::whereEmail($email)->where('created_at', '>', now()->subHours(24))->count();
if($exists && $exists > 3) {
$errorParams = http_build_query([
'status' => 'error',
'message' => 'Too many attempts, please try again later.'
]);
return redirect("pixelfed://verifyEmail?{$errorParams}");
}
DB::beginTransaction();
$registration = AppRegister::create([
'email' => $email,
'verify_code' => $code,
'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("pixelfed://verifyEmail?{$errorParams}");
}
DB::commit();
$queryParams = http_build_query([
'email' => $request->email,
'expires_in' => 3600,
'status' => 'success'
]);
return redirect("pixelfed://verifyEmail?{$errorParams}");
}
}

View file

@ -0,0 +1,55 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class InAppRegisterEmailVerify extends Mailable
{
use Queueable, SerializesModels;
public $code;
/**
* Create a new message instance.
*/
public function __construct($code)
{
$this->code = $code;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: config('pixelfed.domain.app') . ' - Verify Your Email Address',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
markdown: 'emails.iar.email_verify',
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}

View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class AppRegister extends Model
{
protected $guarded = [];
}

View file

@ -112,4 +112,5 @@ return [
],
],
'iar' => env('APP_REGISTER', false),
];

View file

@ -0,0 +1,32 @@
<?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::create('app_registers', function (Blueprint $table) {
$table->id();
$table->string('email');
$table->string('verify_code');
$table->unique(['email', 'verify_code']);
$table->timestamp('email_delivered_at')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('app_registers');
}
};

View file

@ -0,0 +1,31 @@
@component('mail::message')
<div class="otcontainer">
## Verify Your Email Address
<p class="ottext">
Hello,
</p>
<p class="ottext">
Thank you for signing up to {{config('pixelfed.domain.app')}}!
</p>
<p class="ottext">
To complete your registration, please enter the following verification code:
</p>
<div class="otcode">
{{ $code }}
</div>
<p class="ottext">
This code will expire in 60 minutes. If you didn't request this verification, please ignore this email.
</p>
<div class="otfooter">
<p>If you're having trouble with the verification code, please contact our <a href="{{route('site.help')}}">support team</a>.</p>
</div>
</div>
@endcomponent

View file

@ -290,3 +290,34 @@ img {
font-size: 15px;
text-align: center;
}
.otcontainer {
padding: 2rem;
max-width: 600px;
margin: 0 auto;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}
.otcode {
letter-spacing: 0.5rem;
font-size: 2rem;
font-weight: bold;
background-color: #f3f4f6;
padding: 1rem 2rem;
border-radius: 0.5rem;
margin: 2rem 0;
text-align: center;
color: #000000;
}
.ottext {
color: #374151;
line-height: 1.6;
margin: 1rem 0;
}
.otfooter {
margin-top: 2rem;
font-size: 0.875rem;
color: #6b7280;
}

View file

@ -139,6 +139,9 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
Route::get('discover/places/{id}/{slug}', 'PlaceController@show');
Route::get('discover/location/country/{country}', 'PlaceController@directoryCities');
Route::get('/i/app-email-verify', 'AppRegisterController@index');
Route::post('/i/app-email-verify', 'AppRegisterController@store');
Route::group(['prefix' => 'i'], function () {
Route::redirect('/', '/');
Route::get('compose', 'StatusController@compose')->name('compose');