You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pixelfed/app/Http/Controllers/AppRegisterController.php

322 lines
11 KiB
PHTML

2 years ago
<?php
namespace App\Http\Controllers;
use App\Mail\InAppRegisterEmailVerify;
use App\Models\AppRegister;
use App\Services\AccountService;
use App\User;
use App\Util\Lexer\RestrictedNames;
use Illuminate\Http\Request;
2 years ago
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
2 years ago
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use Laravel\Passport\RefreshTokenRepository;
use Purify;
2 years ago
class AppRegisterController extends Controller
{
public function index(Request $request)
{
abort_unless(config('auth.in_app_registration'), 404);
$open = (bool) config_cache('pixelfed.open_registration');
if (! $open || $request->user()) {
2 years ago
return redirect('/');
}
2 years ago
return view('auth.iar');
}
public function store(Request $request)
{
abort_unless(config('auth.in_app_registration'), 404);
$open = (bool) config_cache('pixelfed.open_registration');
if (! $open || $request->user()) {
return redirect('/');
}
2 years ago
$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 = strtolower($request->input('email'));
2 years ago
$code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
DB::beginTransaction();
2 years ago
$exists = AppRegister::whereEmail($email)->where('created_at', '>', now()->subHours(24))->count();
if ($exists && $exists > 3) {
2 years ago
$errorParams = http_build_query([
'status' => 'error',
'message' => 'Too many attempts, please try again later.',
2 years ago
]);
DB::rollBack();
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>
2 years ago
2 years ago
return redirect()->away("pixelfed://verifyEmail?{$errorParams}");
2 years ago
}
$registration = AppRegister::create([
'email' => $email,
'verify_code' => $code,
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>
2 years ago
'uses' => 1,
'email_delivered_at' => now(),
2 years ago
]);
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',
2 years ago
]);
2 years ago
return redirect()->away("pixelfed://verifyEmail?{$errorParams}");
2 years ago
}
DB::commit();
$queryParams = http_build_query([
'email' => $request->email,
'expires_in' => 3600,
'status' => 'success',
2 years ago
]);
2 years ago
return redirect()->away("pixelfed://verifyEmail?{$queryParams}");
}
public function verifyCode(Request $request)
{
abort_unless(config('auth.in_app_registration'), 404);
$open = (bool) config_cache('pixelfed.open_registration');
if (! $open || $request->user()) {
return redirect('/');
}
2 years ago
$this->validate($request, [
'email' => 'required|email:rfc,dns,spoof,strict|unique:users,email',
'verify_code' => ['required', 'digits:6', 'numeric'],
2 years ago
]);
$email = strtolower($request->input('email'));
2 years ago
$code = $request->input('verify_code');
$exists = AppRegister::whereEmail($email)
->whereVerifyCode($code)
->where('created_at', '>', now()->subMinutes(60))
->exists();
return response()->json([
'status' => $exists ? 'success' : 'error',
]);
2 years ago
}
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>
2 years ago
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);
$open = (bool) config_cache('pixelfed.open_registration');
if (! $open || $request->user()) {
return redirect('/');
}
$this->validate($request, [
'email' => 'required|email:rfc,dns,spoof,strict|unique:users,email',
'verify_code' => ['required', 'digits:6', 'numeric'],
'username' => $this->validateUsernameRule(),
'name' => 'nullable|string|max:'.config('pixelfed.max_name_length'),
'password' => 'required|string|min:'.config('pixelfed.min_password_length'),
]);
$email = strtolower($request->input('email'));
$code = $request->input('verify_code');
$username = $request->input('username');
$name = $request->input('name');
$password = $request->input('password');
$exists = AppRegister::whereEmail($email)
->whereVerifyCode($code)
->where('created_at', '>', now()->subMinutes(60))
->exists();
if (! $exists) {
return response()->json([
'status' => 'error',
'message' => 'Invalid verification code, please try again later.',
]);
}
$user = User::create([
'name' => Purify::clean($name),
'username' => $username,
'email' => $email,
'password' => Hash::make($password),
'app_register_ip' => request()->ip(),
'register_source' => 'app',
'email_verified_at' => now(),
]);
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>
2 years ago
sleep(random_int(8, 10));
$user = User::findOrFail($user->id);
$token = $user->createToken('Pixelfed App', ['read', 'write', 'follow', 'push']);
$tokenModel = $token->token;
$clientId = $tokenModel->client_id;
$clientSecret = DB::table('oauth_clients')->where('id', $clientId)->value('secret');
$refreshTokenRepo = app(RefreshTokenRepository::class);
$refreshToken = $refreshTokenRepo->create([
'id' => Str::random(80),
'access_token_id' => $tokenModel->id,
'revoked' => false,
'expires_at' => now()->addDays(config('instance.oauth.refresh_expiration', 400)),
]);
$expiresAt = $tokenModel->expires_at ?? now()->addDays(config('instance.oauth.token_expiration', 356));
$expiresIn = now()->diffInSeconds($expiresAt);
return response()->json([
'status' => 'success',
'token_type' => 'Bearer',
'domain' => config('pixelfed.domain.app'),
'expires_in' => $expiresIn,
'access_token' => $token->accessToken,
'refresh_token' => $refreshToken->id,
'client_id' => $clientId,
'client_secret' => $clientSecret,
'scope' => ['read', 'write', 'follow', 'push'],
'user' => [
'pid' => (string) $user->profile_id,
'username' => $user->username,
],
'account' => AccountService::get($user->profile_id, true),
]);
}
protected function validateUsernameRule()
{
return [
'required',
'min:2',
'max:30',
'unique:users',
function ($attribute, $value, $fail) {
$dash = substr_count($value, '-');
$underscore = substr_count($value, '_');
$period = substr_count($value, '.');
if (ends_with($value, ['.php', '.js', '.css'])) {
return $fail('Username is invalid.');
}
if (($dash + $underscore + $period) > 1) {
return $fail('Username is invalid. Can only contain one dash (-), period (.) or underscore (_).');
}
if (! ctype_alnum($value[0])) {
return $fail('Username is invalid. Must start with a letter or number.');
}
if (! ctype_alnum($value[strlen($value) - 1])) {
return $fail('Username is invalid. Must end with a letter or number.');
}
$val = str_replace(['_', '.', '-'], '', $value);
if (! ctype_alnum($val)) {
return $fail('Username is invalid. Username must be alpha-numeric and may contain dashes (-), periods (.) and underscores (_).');
}
if (! preg_match('/[a-zA-Z]/', $value)) {
return $fail('Username is invalid. Must contain at least one alphabetical character.');
}
$restricted = RestrictedNames::get();
if (in_array(strtolower($value), array_map('strtolower', $restricted))) {
return $fail('Username cannot be used.');
}
},
];
}
2 years ago
}