This commit is contained in:
Pierre Jaury 2018-08-23 22:29:53 +02:00
commit 83c6f4c615
11 changed files with 233 additions and 55 deletions

View file

@ -6,10 +6,21 @@ use Illuminate\Http\Request;
use Carbon\Carbon; use Carbon\Carbon;
use App\Mail\ConfirmEmail; use App\Mail\ConfirmEmail;
use Auth, DB, Cache, Mail, Redis; use Auth, DB, Cache, Mail, Redis;
use App\{EmailVerification, Notification, Profile, User}; use App\{
EmailVerification,
Notification,
Profile,
User,
UserFilter
};
class AccountController extends Controller class AccountController extends Controller
{ {
protected $filters = [
'user.mute',
'user.block'
];
public function __construct() public function __construct()
{ {
$this->middleware('auth'); $this->middleware('auth');
@ -134,4 +145,97 @@ class AccountController extends Controller
return $notifications; 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();
}
} }

View file

@ -51,11 +51,22 @@ class RegisterController extends Controller
protected function validator(array $data) protected function validator(array $data)
{ {
$this->validateUsername($data['username']); $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 = [ $rules = [
'name' => 'required|string|max:255', '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', 'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed', 'password' => 'required|string|min:6|confirmed',
]; ];

View file

@ -18,7 +18,12 @@ class ProfileController extends Controller
public function show(Request $request, $username) public function show(Request $request, $username)
{ {
$user = Profile::whereUsername($username)->firstOrFail(); $user = Profile::whereUsername($username)->firstOrFail();
if($user->remote_url) {
$settings = new \StdClass;
$settings->crawlable = false;
} else {
$settings = User::whereUsername($username)->firstOrFail()->settings; $settings = User::whereUsername($username)->firstOrFail()->settings;
}
if($request->wantsJson() && config('pixelfed.activitypub_enabled')) { if($request->wantsJson() && config('pixelfed.activitypub_enabled')) {
return $this->showActivityPub($request, $user); return $this->showActivityPub($request, $user);
@ -37,6 +42,7 @@ class ProfileController extends Controller
$timeline = $user->statuses() $timeline = $user->statuses()
->whereHas('media') ->whereHas('media')
->whereNull('in_reply_to_id') ->whereNull('in_reply_to_id')
->whereNull('reblog_of_id')
->orderBy('created_at','desc') ->orderBy('created_at','desc')
->withCount(['comments', 'likes']) ->withCount(['comments', 'likes'])
->simplePaginate(21); ->simplePaginate(21);

View file

@ -44,29 +44,33 @@ class SettingsController extends Controller
$user = Auth::user(); $user = Auth::user();
$profile = $user->profile; $profile = $user->profile;
$validate = config('pixelfed.enforce_email_verification');
if($user->email != $email) { if($user->email != $email) {
$changes = true; $changes = true;
$user->email = $email; $user->email = $email;
if($validate) {
$user->email_verified_at = null; $user->email_verified_at = null;
// Prevent old verifications from working // Prevent old verifications from working
EmailVerification::whereUserId($user->id)->delete(); EmailVerification::whereUserId($user->id)->delete();
} }
}
// Only allow email to be updated if not yet verified // 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) { if($profile->name != $name) {
$changes = true; $changes = true;
$user->name = $name; $user->name = $name;
$profile->name = $name; $profile->name = $name;
} }
if($profile->website != $website) { if(!$profile->website || $profile->website != $website) {
$changes = true; $changes = true;
$profile->website = $website; $profile->website = $website;
} }
if($profile->bio != $bio) { if(!$profile->bio || !$profile->bio != $bio) {
$changes = true; $changes = true;
$profile->bio = $bio; $profile->bio = $bio;
} }
@ -167,6 +171,8 @@ class SettingsController extends Controller
$fields = [ $fields = [
'is_private', 'is_private',
'crawlable', 'crawlable',
'show_profile_follower_count',
'show_profile_following_count'
]; ];
foreach($fields as $field) { foreach($fields as $field) {
$form = $request->input($field); $form = $request->input($field);

View file

@ -6,5 +6,10 @@ use Illuminate\Database\Eloquent\Model;
class UserFilter extends Model class UserFilter extends Model
{ {
// protected $fillable = [
'user_id',
'filterable_id',
'filterable_type',
'filter_type'
];
} }

View file

@ -0,0 +1,36 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class UpdateSettingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('user_settings', function (Blueprint $table) {
$table->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');
}
}

View file

@ -21,8 +21,8 @@
</div> </div>
</div> </div>
</div> </div>
<div class="tag-timeline">
<div class="tag-timeline row"> <div class="row">
@foreach($posts as $status) @foreach($posts as $status)
<div class="col-4 p-0 p-sm-2 p-md-3"> <div class="col-4 p-0 p-sm-2 p-md-3">
<a class="card info-overlay card-md-border-0" href="{{$status->url()}}"> <a class="card info-overlay card-md-border-0" href="{{$status->url()}}">
@ -43,6 +43,7 @@
</div> </div>
@endforeach @endforeach
</div> </div>
</div>
<div class="d-flex justify-content-center pagination-container mt-4"> <div class="d-flex justify-content-center pagination-container mt-4">
{{$posts->links()}} {{$posts->links()}}
</div> </div>

View file

@ -30,7 +30,7 @@
<li class="nav-item px-2"> <li class="nav-item px-2">
<div title="Create new post" data-toggle="tooltip" data-placement="bottom"> <div title="Create new post" data-toggle="tooltip" data-placement="bottom">
<a href="{{route('compose')}}" class="nav-link" data-toggle="modal" data-target="#composeModal"> <a href="{{route('compose')}}" class="nav-link" data-toggle="modal" data-target="#composeModal">
<i class="far fa-plus-square fa-lg text-primary"></i> <i class="fas fa-camera-retro fa-lg text-primary"></i>
</a> </a>
</div> </div>
</li> </li>

View file

@ -53,7 +53,7 @@
<div class="profile-stats pb-3 d-inline-flex lead"> <div class="profile-stats pb-3 d-inline-flex lead">
<div class="font-weight-light pr-5"> <div class="font-weight-light pr-5">
<a class="text-dark" href="{{$user->url()}}"> <a class="text-dark" href="{{$user->url()}}">
<span class="font-weight-bold">{{$user->statuses()->whereNull('in_reply_to_id')->count()}}</span> <span class="font-weight-bold">{{$user->statuses()->whereNull('reblog_of_id')->whereNull('in_reply_to_id')->count()}}</span>
Posts Posts
</a> </a>
</div> </div>
@ -70,13 +70,14 @@
</a> </a>
</div> </div>
</div> </div>
<p class="lead"> <p class="lead mb-0">
<span class="font-weight-bold">{{$user->name}}</span> <span class="font-weight-bold">{{$user->name}}</span>
@if($user->remote_url) @if($user->remote_url)
<span class="badge badge-info">REMOTE PROFILE</span> <span class="badge badge-info">REMOTE PROFILE</span>
@endif @endif
{{$user->bio}}
</p> </p>
<p class="mb-0 lead">{{$user->bio}}</p>
<p class="mb-0"><a href="{{$user->website}}" class="font-weight-bold" rel="external nofollow noopener" target="_blank">{{str_limit($user->website, 30)}}</a></p>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,21 +0,0 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class InstalledTest extends TestCase
{
public function testLandingTest()
{
$response = $this->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"]
]]);
}
}