mirror of
https://github.com/pixelfed/pixelfed.git
synced 2025-03-11 22:53:07 +00:00
Add app register email verify resends (#5814)
* Update iar.blade.php - Fix in-app reg without hcaptcha (#5807) * Staging (#5674) * Update .env.docker Registry has changed. Old registry has been discontinued in August 2024. New Registry added, format of Docker tag has been adjusted as it now contains the Debian Release as well. Sample Version is set to current stable but can be adjusted to any of the available branches. * Update .env.docker Stick major.minor according to https://jippi.github.io/docker-pixelfed/customize/tags/#pixelfed-version Disable Debian Release Check until it's solved in dottie. Closes https://github.com/pixelfed/pixelfed/issues/5264 * New translations web.php (Finnish) [ci skip] * New translations web.php (Finnish) [ci skip] * fix: don't restore memory limit after cities import Since this command can only be invoked by CLI, the process will exit after a successful import, so restoring the transient PHP memory limit doesn't really have any affect. In PHP 8.4, this throws the following error (which doesn't happen in 8.3 and below) > [entrypoint / 11-first-time-setup.sh] - (stderr) 128769/128769 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%[2025-01-20 11:29:23] production.ERROR: Failed to set memory limit to 134217728 bytes (Current memory usage is 134746112 bytes) {"exception":"[object] (ErrorException(code: 0): Failed to set memory limit to 134217728 bytes (Current memory usage is 134746112 bytes) at /var/www/app/Console/Commands/ImportCities.php:140) It seems to be a 8.4 behavior change, so removing the logic would make it go away * New translations web.php (Finnish) [ci skip] * New translations web.php (Finnish) [ci skip] * New translations web.php (Portuguese) [ci skip] * New translations web.php (Portuguese) [ci skip] * fix(compose-modal): avoid WebGL if it's not needed * fix(compose-modal): update webgl-media-editor * New translations web.php (Hungarian) [ci skip] * New translations web.php (Russian) [ci skip] * New translations web.php (Russian) [ci skip] * Update .env.example Adding the parameter INSTANCE_DISCOVER_PUBLIC="true" to prevent a HTTP 403 error at the explorer tab in the instance preview. * New variable for lang spanish * Variable for lang spanish * Update Dockerfile, fixes #5535 #5559 * Fix #5582 * Fix #5632 * Update status twitter:card to summary_large_image for images/albums * Update changelog --------- Co-authored-by: Lioh Moeller <lioh.moeller@gmx.net> Co-authored-by: Christian Winther <jippignu@gmail.com> Co-authored-by: Taye Adeyemi <dev@taye.me> Co-authored-by: stemy2 <stemy2@users.noreply.github.com> Co-authored-by: Uthanien <feldarec@gmail.com> * Update iar.blade.php --------- Co-authored-by: daniel <danielsupernault@gmail.com> Co-authored-by: Lioh Moeller <lioh.moeller@gmx.net> Co-authored-by: Christian Winther <jippignu@gmail.com> Co-authored-by: Taye Adeyemi <dev@taye.me> Co-authored-by: stemy2 <stemy2@users.noreply.github.com> Co-authored-by: Uthanien <feldarec@gmail.com> * Add app register email verify resends * Update composer * Update changelog * Update IG import command --------- Co-authored-by: Shlee <github@shl.ee> Co-authored-by: Lioh Moeller <lioh.moeller@gmx.net> Co-authored-by: Christian Winther <jippignu@gmail.com> Co-authored-by: Taye Adeyemi <dev@taye.me> Co-authored-by: stemy2 <stemy2@users.noreply.github.com> Co-authored-by: Uthanien <feldarec@gmail.com>
This commit is contained in:
parent
af7c76cd10
commit
d066a5cff5
11 changed files with 852 additions and 533 deletions
|
@ -2,6 +2,9 @@
|
|||
|
||||
## [Unreleased](https://github.com/pixelfed/pixelfed/compare/v0.12.3...dev)
|
||||
|
||||
### Added
|
||||
- Add app register email verify resends ([dbd1e17](https://github.com/pixelfed/pixelfed/commit/dbd1e17))
|
||||
|
||||
### Features
|
||||
- WebGL photo filters ([#5374](https://github.com/pixelfed/pixelfed/pull/5374))
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class TransformImports extends Command
|
|||
return;
|
||||
}
|
||||
|
||||
$ips = ImportPost::whereNull('status_id')->where('skip_missing_media', '!=', true)->take(500)->get();
|
||||
$ips = ImportPost::whereNull('status_id')->where('skip_missing_media', '!=', true)->take(1500)->get();
|
||||
|
||||
if (! $ips->count()) {
|
||||
return;
|
||||
|
|
|
@ -38,7 +38,7 @@ class Kernel extends ConsoleKernel
|
|||
}
|
||||
|
||||
if (config('import.instagram.enabled')) {
|
||||
$schedule->command('app:transform-imports')->everyTenMinutes()->onOneServer();
|
||||
$schedule->command('app:transform-imports')->twiceDaily(13, 22)->onOneServer();
|
||||
$schedule->command('app:import-upload-garbage-collection')->hourlyAt(51)->onOneServer();
|
||||
$schedule->command('app:import-remove-deleted-accounts')->hourlyAt(37)->onOneServer();
|
||||
$schedule->command('app:import-upload-clean-storage')->twiceDailyAt(1, 13, 32)->onOneServer();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"bacon/bacon-qr-code": "^2.0.3",
|
||||
"bacon/bacon-qr-code": "^3.0",
|
||||
"brick/math": "^0.9.3",
|
||||
"buzz/laravel-h-captcha": "^1.0.4",
|
||||
"doctrine/dbal": "^3.0",
|
||||
"endroid/qr-code": "^6.0",
|
||||
"intervention/image": "^2.4",
|
||||
"jenssegers/agent": "^2.6",
|
||||
"laravel-notification-channels/expo": "~1.3.0|~2.0.0",
|
||||
|
|
1099
composer.lock
generated
1099
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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');
|
||||
});
|
||||
}
|
||||
};
|
145
resources/views/auth/iar-resend.blade.php
Normal file
145
resources/views/auth/iar-resend.blade.php
Normal file
|
@ -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…
Add table
Reference in a new issue