middleware('guest'); } public function getRegisterToken() { return \Cache::remember('pf:register:rt', 900, function() { return str_random(40); }); } /** * Get a validator for an incoming registration request. * * @param array $data * * @return \Illuminate\Contracts\Validation\Validator */ protected function validator(array $data) { if(config('database.default') == 'pgsql') { $data['username'] = strtolower($data['username']); $data['email'] = strtolower($data['email']); } $usernameRules = [ 'required', 'min:2', 'max:15', '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 (_).'); } $restricted = RestrictedNames::get(); if (in_array(strtolower($value), array_map('strtolower', $restricted))) { return $fail('Username cannot be used.'); } }, ]; $emailRules = [ 'required', 'string', 'email', 'max:255', 'unique:users', function ($attribute, $value, $fail) { $banned = EmailService::isBanned($value); if($banned) { return $fail('Email is invalid.'); } }, ]; $rt = [ 'required', function ($attribute, $value, $fail) { if($value !== $this->getRegisterToken()) { return $fail('Something went wrong'); } } ]; $rules = [ 'agecheck' => 'required|accepted', 'rt' => $rt, 'name' => 'nullable|string|max:'.config('pixelfed.max_name_length'), 'username' => $usernameRules, 'email' => $emailRules, 'password' => 'required|string|min:'.config('pixelfed.min_password_length').'|confirmed', ]; if(config('captcha.enabled')) { $rules['h-captcha-response'] = 'required|captcha'; } return Validator::make($data, $rules); } /** * Create a new user instance after a valid registration. * * @param array $data * * @return \App\User */ protected function create(array $data) { if(config('database.default') == 'pgsql') { $data['username'] = strtolower($data['username']); $data['email'] = strtolower($data['email']); } return User::create([ 'name' => Purify::clean($data['name']), 'username' => $data['username'], 'email' => $data['email'], 'password' => Hash::make($data['password']), ]); } /** * Show the application registration form. * * @return \Illuminate\Http\Response */ public function showRegistrationForm() { if(config_cache('pixelfed.open_registration')) { if(config('pixelfed.bouncer.cloud_ips.ban_signups')) { abort_if(BouncerService::checkIp(request()->ip()), 404); } $limit = config('pixelfed.max_users'); if($limit) { abort_if($limit <= User::count(), 404); return view('auth.register'); } else { return view('auth.register'); } } else { abort(404); } } /** * Handle a registration request for the application. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function register(Request $request) { abort_if(config_cache('pixelfed.open_registration') == false, 400); if(config('pixelfed.bouncer.cloud_ips.ban_signups')) { abort_if(BouncerService::checkIp($request->ip()), 404); } $count = User::count(); $limit = config('pixelfed.max_users'); if(false == config_cache('pixelfed.open_registration') || $limit && $limit <= $count) { return abort(403); } $this->validator($request->all())->validate(); event(new Registered($user = $this->create($request->all()))); $this->guard()->login($user); return $this->registered($request, $user) ?: redirect($this->redirectPath()); } }