diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index d3abf4dc8..76a47e938 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -6,10 +6,21 @@ use Illuminate\Http\Request; use Carbon\Carbon; use App\Mail\ConfirmEmail; use Auth, DB, Cache, Mail, Redis; -use App\{EmailVerification, Notification, Profile, User}; +use App\{ + EmailVerification, + Notification, + Profile, + User, + UserFilter +}; class AccountController extends Controller { + protected $filters = [ + 'user.mute', + 'user.block' + ]; + public function __construct() { $this->middleware('auth'); @@ -134,4 +145,97 @@ class AccountController extends Controller return $notifications; } + public function messages() + { + return view('account.messages'); + } + + + public function showMessage(Request $request, $id) + { + return view('account.message'); + } + + public function mute(Request $request) + { + $this->validate($request, [ + 'type' => 'required|string', + 'item' => 'required|integer|min:1' + ]); + + $user = Auth::user()->profile; + $type = $request->input('type'); + $item = $request->input('item'); + $action = "{$type}.mute"; + + if(!in_array($action, $this->filters)) { + return abort(406); + } + $filterable = []; + switch ($type) { + case 'user': + $profile = Profile::findOrFail($item); + if($profile->id == $user->id) { + return abort(403); + } + $class = get_class($profile); + $filterable['id'] = $profile->id; + $filterable['type'] = $class; + break; + + default: + # code... + break; + } + + $filter = UserFilter::firstOrCreate([ + 'user_id' => $user->id, + 'filterable_id' => $filterable['id'], + 'filterable_type' => $filterable['type'], + 'filter_type' => 'mute' + ]); + + return redirect()->back(); + + } + + public function block(Request $request) + { + $this->validate($request, [ + 'type' => 'required|string', + 'item' => 'required|integer|min:1' + ]); + + $user = Auth::user()->profile; + $type = $request->input('type'); + $item = $request->input('item'); + $action = "{$type}.block"; + if(!in_array($action, $this->filters)) { + return abort(406); + } + $filterable = []; + switch ($type) { + case 'user': + $profile = Profile::findOrFail($item); + $class = get_class($profile); + $filterable['id'] = $profile->id; + $filterable['type'] = $class; + break; + + default: + # code... + break; + } + + $filter = UserFilter::firstOrCreate([ + 'user_id' => $user->id, + 'filterable_id' => $filterable['id'], + 'filterable_type' => $filterable['type'], + 'filter_type' => 'block' + ]); + + return redirect()->back(); + + } + } diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 1b9de0513..f9ba3b648 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -51,11 +51,22 @@ class RegisterController extends Controller protected function validator(array $data) { $this->validateUsername($data['username']); - + $usernameRules = [ + 'required', + 'alpha_dash', + 'min:2', + 'max:15', + 'unique:users', + function($attribute, $value, $fail) { + if(!ctype_alpha($value[0])) { + return $fail($attribute . ' is invalid. Username must be alpha-numeric and start with a letter.'); + } + } + ]; $rules = [ 'name' => 'required|string|max:255', - 'username' => 'required|alpha_dash|min:2|max:15|unique:users', + 'username' => $usernameRules, 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', ]; diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 985df88ed..4e647caba 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -18,7 +18,12 @@ class ProfileController extends Controller public function show(Request $request, $username) { $user = Profile::whereUsername($username)->firstOrFail(); - $settings = User::whereUsername($username)->firstOrFail()->settings; + if($user->remote_url) { + $settings = new \StdClass; + $settings->crawlable = false; + } else { + $settings = User::whereUsername($username)->firstOrFail()->settings; + } if($request->wantsJson() && config('pixelfed.activitypub_enabled')) { return $this->showActivityPub($request, $user); @@ -37,6 +42,7 @@ class ProfileController extends Controller $timeline = $user->statuses() ->whereHas('media') ->whereNull('in_reply_to_id') + ->whereNull('reblog_of_id') ->orderBy('created_at','desc') ->withCount(['comments', 'likes']) ->simplePaginate(21); diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 95859efa7..ab8f35ce9 100644 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -44,29 +44,33 @@ class SettingsController extends Controller $user = Auth::user(); $profile = $user->profile; + $validate = config('pixelfed.enforce_email_verification'); if($user->email != $email) { $changes = true; $user->email = $email; - $user->email_verified_at = null; - // Prevent old verifications from working - EmailVerification::whereUserId($user->id)->delete(); + + if($validate) { + $user->email_verified_at = null; + // Prevent old verifications from working + EmailVerification::whereUserId($user->id)->delete(); + } } // Only allow email to be updated if not yet verified - if(!$changes && $user->email_verified_at) { + if(!$validate || !$changes && $user->email_verified_at) { if($profile->name != $name) { $changes = true; $user->name = $name; $profile->name = $name; } - if($profile->website != $website) { + if(!$profile->website || $profile->website != $website) { $changes = true; $profile->website = $website; } - if($profile->bio != $bio) { + if(!$profile->bio || !$profile->bio != $bio) { $changes = true; $profile->bio = $bio; } @@ -167,6 +171,8 @@ class SettingsController extends Controller $fields = [ 'is_private', 'crawlable', + 'show_profile_follower_count', + 'show_profile_following_count' ]; foreach($fields as $field) { $form = $request->input($field); diff --git a/app/UserFilter.php b/app/UserFilter.php index 071f2eeb4..41edd5398 100644 --- a/app/UserFilter.php +++ b/app/UserFilter.php @@ -6,5 +6,10 @@ use Illuminate\Database\Eloquent\Model; class UserFilter extends Model { - // + protected $fillable = [ + 'user_id', + 'filterable_id', + 'filterable_type', + 'filter_type' + ]; } diff --git a/database/migrations/2018_08_22_022306_update_settings_table.php b/database/migrations/2018_08_22_022306_update_settings_table.php new file mode 100644 index 000000000..500612903 --- /dev/null +++ b/database/migrations/2018_08_22_022306_update_settings_table.php @@ -0,0 +1,36 @@ +boolean('show_profile_followers')->default(true); + $table->boolean('show_profile_follower_count')->default(true); + $table->boolean('show_profile_following')->default(true); + $table->boolean('show_profile_following_count')->default(true); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $table->dropColumn('show_profile_followers'); + $table->dropColumn('show_profile_follower_count'); + $table->dropColumn('show_profile_following'); + $table->dropColumn('show_profile_following_count'); + } +} diff --git a/resources/views/discover/tags/show.blade.php b/resources/views/discover/tags/show.blade.php index 542f134c2..a710ae365 100644 --- a/resources/views/discover/tags/show.blade.php +++ b/resources/views/discover/tags/show.blade.php @@ -21,27 +21,28 @@ - -
diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php deleted file mode 100644 index f31e495ca..000000000 --- a/tests/Feature/ExampleTest.php +++ /dev/null @@ -1,21 +0,0 @@ -get('/'); - - $response->assertStatus(200); - } -} diff --git a/tests/Feature/InstalledTest.php b/tests/Feature/InstalledTest.php new file mode 100644 index 000000000..0f9aa6d6b --- /dev/null +++ b/tests/Feature/InstalledTest.php @@ -0,0 +1,29 @@ +get('/'); + $response + ->assertStatus(200) + ->assertSeeText('Image Sharing for Everyone'); + } + + public function testNodeinfoTest() + { + $response = $this->get('/.well-known/nodeinfo'); + $response + ->assertStatus(200) + ->assertJson([ + "links" => [ + ["rel" => "http://nodeinfo.diaspora.software/ns/schema/2.0"] + ]]); + } +}