From cc8337888e3a241bfbd59f835e1dbb1907b2810b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Mon, 11 Feb 2019 19:37:14 -0700 Subject: [PATCH 1/9] Update password reset --- resources/lang/en/passwords.php | 4 ++-- resources/views/auth/passwords/email.blade.php | 12 +++--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/resources/lang/en/passwords.php b/resources/lang/en/passwords.php index ffa19ba40..8975d113f 100644 --- a/resources/lang/en/passwords.php +++ b/resources/lang/en/passwords.php @@ -15,8 +15,8 @@ return [ 'password' => 'Passwords must be at least six characters and match the confirmation.', 'reset' => 'Your password has been reset!', - 'sent' => 'We have e-mailed your password reset link!', + 'sent' => 'If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes. Please check your spam folder if you didn\'t receive this email.', 'token' => 'This password reset token is invalid.', - 'user' => "We can't find a user with that e-mail address.", + 'user' => 'If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes. Please check your spam folder if you didn\'t receive this email.', ]; diff --git a/resources/views/auth/passwords/email.blade.php b/resources/views/auth/passwords/email.blade.php index 5bfda773e..2b27a5508 100644 --- a/resources/views/auth/passwords/email.blade.php +++ b/resources/views/auth/passwords/email.blade.php @@ -8,9 +8,9 @@
{{ __('Reset Password') }}
- @if (session('status')) + @if (session('status') || $errors->has('email'))
- {{ session('status') }} + {{ session('status') ?? $errors->first('email') }}
@endif @@ -19,13 +19,7 @@
- - - @if ($errors->has('email')) - - {{ $errors->first('email') }} - - @endif +
From 8de42c786202fe021148dc046d44cf0eafabc220 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 12 Feb 2019 00:38:29 -0700 Subject: [PATCH 2/9] Update Avatar model --- app/Avatar.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Avatar.php b/app/Avatar.php index b72510765..76ca442b9 100644 --- a/app/Avatar.php +++ b/app/Avatar.php @@ -15,4 +15,9 @@ class Avatar extends Model * @var array */ protected $dates = ['deleted_at']; + + public function profile() + { + return $this->belongsTo(Profile::class); + } } From 03cf26a09ad721344484da0b1353513a8c820993 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 12 Feb 2019 00:57:49 -0700 Subject: [PATCH 3/9] Update UserObserver --- app/{Observer => Observers}/UserObserver.php | 0 app/Providers/AppServiceProvider.php | 16 +++------------- 2 files changed, 3 insertions(+), 13 deletions(-) rename app/{Observer => Observers}/UserObserver.php (100%) diff --git a/app/Observer/UserObserver.php b/app/Observers/UserObserver.php similarity index 100% rename from app/Observer/UserObserver.php rename to app/Observers/UserObserver.php diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index dca968bb5..982b462ec 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -4,8 +4,7 @@ namespace App\Providers; use App\Observers\UserObserver; use App\User; -use Auth; -use Horizon; +use Auth, Horizon, URL; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; @@ -43,17 +42,8 @@ class AppServiceProvider extends ServiceProvider }); Blade::directive('prettySize', function ($expression) { - $size = intval($expression); - $precision = 0; - $short = true; - $units = $short ? - ['B', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] : - ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) { - } - $res = round($size, $precision).$units[$i]; - - return ""; + $size = \App\Util\Lexer\PrettyNumber::size($expression); + return ""; }); Blade::directive('maxFileSize', function () { From db22469f0692d2278b1881f6432e151551d9403d Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 12 Feb 2019 01:05:17 -0700 Subject: [PATCH 4/9] Add AvatarObserver --- app/Observers/AvatarObserver.php | 75 ++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 app/Observers/AvatarObserver.php diff --git a/app/Observers/AvatarObserver.php b/app/Observers/AvatarObserver.php new file mode 100644 index 000000000..cdc2faa12 --- /dev/null +++ b/app/Observers/AvatarObserver.php @@ -0,0 +1,75 @@ +media_path); + @unlink($path); + } + + /** + * Handle the avatar "restored" event. + * + * @param \App\Avatar $avatar + * @return void + */ + public function restored(Avatar $avatar) + { + // + } + + /** + * Handle the avatar "force deleted" event. + * + * @param \App\Avatar $avatar + * @return void + */ + public function forceDeleted(Avatar $avatar) + { + // + } +} From 955593101bc6d28160b472305cad792f80ff8b8d Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 12 Feb 2019 01:05:43 -0700 Subject: [PATCH 5/9] Update AppServiceProvider --- app/Providers/AppServiceProvider.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 982b462ec..fe6d8f991 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,8 +2,11 @@ namespace App\Providers; -use App\Observers\UserObserver; -use App\User; +use App\Observers\{ + AvatarObserver, + UserObserver +}; +use App\{Avatar,User}; use Auth, Horizon, URL; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Schema; @@ -20,6 +23,7 @@ class AppServiceProvider extends ServiceProvider { Schema::defaultStringLength(191); + Avatar::observe(AvatarObserver::class); User::observe(UserObserver::class); Horizon::auth(function ($request) { From 4eeb1f02472a689b868508ae6ab83954212c0c12 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 12 Feb 2019 01:10:29 -0700 Subject: [PATCH 6/9] Add duplicate profile fix --- app/Console/Commands/FixDuplicateProfiles.php | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 app/Console/Commands/FixDuplicateProfiles.php diff --git a/app/Console/Commands/FixDuplicateProfiles.php b/app/Console/Commands/FixDuplicateProfiles.php new file mode 100644 index 000000000..a9cab3ec0 --- /dev/null +++ b/app/Console/Commands/FixDuplicateProfiles.php @@ -0,0 +1,75 @@ +whereNotNull('user_id')->groupBy('user_id')->orderBy('user_id', 'desc')->get()->where('count', '>', 1); + $count = $profiles->count(); + if($count == 0) { + $this->info("No duplicate profiles found!"); + return; + } + $this->info("Found {$count} accounts with duplicate profiles..."); + $bar = $this->output->createProgressBar($count); + $bar->start(); + + foreach ($profiles as $profile) { + $dup = Profile::whereUserId($profile->user_id)->get(); + + if( + $dup->first()->username === $dup->last()->username && + $dup->last()->statuses()->count() == 0 && + $dup->last()->followers()->count() == 0 && + $dup->last()->likes()->count() == 0 && + $dup->last()->media()->count() == 0 + ) { + $dup->last()->avatar->forceDelete(); + $dup->last()->forceDelete(); + } + $bar->advance(); + } + $bar->finish(); + } +} From f38bad4a9c8e7867f612758bb55b2f1edb48830a Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 12 Feb 2019 01:11:02 -0700 Subject: [PATCH 7/9] Update AdminController --- app/Http/Controllers/AdminController.php | 40 +++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index e2adf6bb8..fa4139989 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -26,6 +26,7 @@ use App\Http\Controllers\Admin\{ AdminSettingsController }; use App\Util\Lexer\PrettyNumber; +use Illuminate\Validation\Rule; class AdminController extends Controller { @@ -181,10 +182,47 @@ class AdminController extends Controller public function profiles(Request $request) { - $profiles = Profile::orderBy('id','desc')->paginate(10); + $this->validate($request, [ + 'search' => 'nullable|string|max:250', + 'filter' => [ + 'nullable', + 'string', + Rule::in(['id','username','statuses_count','followers_count','likes_count']) + ], + 'order' => [ + 'nullable', + 'string', + Rule::in(['asc','desc']) + ], + 'layout' => [ + 'nullable', + 'string', + Rule::in(['card','list']) + ], + 'limit' => 'nullable|integer|min:1|max:50' + ]); + $search = $request->input('search'); + $filter = $request->input('filter'); + $order = $request->input('order') ?? 'desc'; + $limit = $request->input('limit') ?? 12; + if($search) { + $profiles = Profile::where('username','like', "%$search%")->orderBy('id','desc')->paginate($limit); + } else if($filter && $order) { + $profiles = Profile::withCount(['likes','statuses','followers'])->orderBy($filter, $order)->paginate($limit); + } else { + $profiles = Profile::orderBy('id','desc')->paginate($limit); + } + return view('admin.profiles.home', compact('profiles')); } + public function profileShow(Request $request, $id) + { + $profile = Profile::findOrFail($id); + $user = $profile->user; + return view('admin.profiles.edit', compact('profile', 'user')); + } + public function appsHome(Request $request) { $filter = $request->input('filter'); From 27690f3efa43dc0298fc689ce997c98add136ed5 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 12 Feb 2019 01:11:26 -0700 Subject: [PATCH 8/9] Update web routes --- routes/web.php | 1 + 1 file changed, 1 insertion(+) diff --git a/routes/web.php b/routes/web.php index 49d509d80..860a4c440 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,6 +13,7 @@ Route::domain(config('pixelfed.domain.admin'))->prefix('i/admin')->group(functio Route::get('statuses/show/{id}', 'AdminController@showStatus'); Route::redirect('profiles', '/i/admin/profiles/list'); Route::get('profiles/list', 'AdminController@profiles')->name('admin.profiles'); + Route::get('profiles/edit/{id}', 'AdminController@profileShow'); Route::redirect('users', '/users/list'); Route::get('users/list', 'AdminController@users')->name('admin.users'); Route::get('users/edit/{id}', 'AdminController@editUser'); From afe18e02ed417e712428320a1049589e447d2ac1 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 12 Feb 2019 01:13:38 -0700 Subject: [PATCH 9/9] Update admin views --- resources/views/admin/profiles/edit.blade.php | 234 ++++++++++++++ resources/views/admin/profiles/home.blade.php | 295 ++++++++++++++++-- resources/views/admin/reports/home.blade.php | 6 +- 3 files changed, 500 insertions(+), 35 deletions(-) create mode 100644 resources/views/admin/profiles/edit.blade.php diff --git a/resources/views/admin/profiles/edit.blade.php b/resources/views/admin/profiles/edit.blade.php new file mode 100644 index 000000000..7d96dfe90 --- /dev/null +++ b/resources/views/admin/profiles/edit.blade.php @@ -0,0 +1,234 @@ +@extends('admin.partial.template-full') + +@section('section') +
+ Back +

Edit Profile

+ Enable Editing +
+
+ +
+
+
+
+ +
+ {{-- --}} +
+
+
+ + + @if($user) + + + + + @endif + + + + + + + + + + + + + + + + + @if($user) + + + + + @endif + +
user id{{$user->id}}
profile id{{$profile->id}}
username + {{$profile->username}} + @if($user && $user->is_admin == true) + Admin + @endif +
display name{{$profile->name}}
joined{{$profile->created_at->format('M j Y')}}
email + {{$user->email}} + @if($user->email_verified_at) + Verified + @else + Unverified + @endif +
+ {{--
+

+ {{$profile->username}} +

+

+ {{$profile->emailUrl()}} +

+

+ Member Since: {{$profile->created_at->format('M Y')}} +

+
--}} +
+
+
+
+
+
+

{{$profile->statusCount()}}

+

Posts

+
+
+
+
+
+
+

{{$profile->followingCount()}}

+

Following

+
+
+
+
+
+
+

{{$profile->followerCount()}}

+

Followers

+
+
+
+
+
+
+

{{$profile->bookmarks()->count()}}

+

Bookmarks

+
+
+
+
+
+
+

{{$profile->likes()->count()}}

+

Likes

+
+
+
+
+
+
+

{{$profile->reports()->count()}}

+

Reports Made

+
+
+
+
+
+
+

{{PrettyNumber::size($profile->media()->sum('size'))}}

+

Storage Used

+
+
+
+
+ +
+ {{--
+
+ Account Settings +
+
+
+ + +
+
+ + +
+
+ + +

+ @if($user->email_verified_at) + Verified for {{$user->email_verified_at->diffForHumans()}} + @else + Unverified email. + @endif +

+
+
+
+
--}} +
+
+ Account Actions +
+
+ +
+
+ @csrf + + +

Adds a CW to every post made by this account.

+
+
+
+
+ @csrf + + +

Removes account from public/network timelines.

+
+
+
+
+ @csrf + + +

Do not transform mentions, hashtags or urls into HTML.

+
+
+
+
+ @csrf + + +

Temporarily disable account until next time user log in.

+
+
+ +
+
+ @csrf + + +

This prevents any new interactions, without deleting existing data.

+
+
+ +
+
+ @csrf + + +

This disables the account and changes the password, forcing account to reset password via verified email.

+
+
+ +
+
+ @csrf + + +

Permanently delete this account.

+
+
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/admin/profiles/home.blade.php b/resources/views/admin/profiles/home.blade.php index dbcef56d2..80017bc61 100644 --- a/resources/views/admin/profiles/home.blade.php +++ b/resources/views/admin/profiles/home.blade.php @@ -4,10 +4,22 @@

Profiles

- + - + - -

- CW - Remote Media - Images - Videos - Stories - Banned - Reported - Unlisted -


-@if(request()->input('layout') == 'list') +@if(request()->input('layout') !== 'card') +
+
+ + + 0 + + items selected + + + + + Apply + + +
+
- + + - - - + + + @foreach($profiles as $profile) - + + + + + + + @endforeach
+
+ + +
+
- ID - - Username + + ID + @if(request()->filter && request()->filter == 'id' && request()->order == 'asc') + + @else + + @endif + - Statuses + + Username + @if(request()->filter && request()->filter == 'username' && request()->order == 'asc') + + @else + + @endif + - Storage + + + Followers + @if(request()->filter && request()->filter == 'followers_count' && request()->order == 'asc') + + @else + + @endif + + + + Likes + @if(request()->filter && request()->filter == 'likes_count' && request()->order == 'asc') + + @else + + @endif + + + + Statuses + @if(request()->filter && request()->filter == 'statuses_count' && request()->order == 'asc') + + @else + + @endif + + + + Storage + + Actions
- {{$profile->id}} + +
+ + +
+ {{$profile->id}} + + {{$profile->username}} + + {{$profile->followers()->count()}} + + {{$profile->likes()->count()}} + + {{$profile->statuses()->count()}} + +
{{$profile->media()->sum('size')}} bytes
+ +
+ Edit +
- {{$profiles->links()}} + {{$profiles->appends([ + 'layout'=>request()->layout, + 'search'=>request()->search, + 'filter'=>request()->filter, + 'order'=>request()->order + ])->links()}}
@else
@@ -84,7 +188,7 @@
- +

{{$profile->username}}

@@ -112,7 +216,12 @@ @endforeach
- {{$profiles->links()}} + {{$profiles->appends([ + 'layout'=>request()->layout, + 'search'=>request()->search, + 'filter'=>request()->filter, + 'order'=>request()->order + ])->links()}}
@endif @endsection @@ -124,7 +233,8 @@ display: none; } -.user-row:hover { +.user-row:hover, +.user-row-active { background-color: #eff8ff; } .user-row:hover .action-row { @@ -140,5 +250,128 @@ $('.filesize').each(function(k,v) { $(this).text(filesize(v.getAttribute('data-size'), {unix:true, round:0})) }); + $('.col-ord').on('click', function(e) { + e.preventDefault(); + let el = $(this); + let ord = el.data('dir'); + let col = el.data('col'); + let wurl = new URL(window.location.href); + let query_string = wurl.search; + let search_params = new URLSearchParams(query_string); + + if(ord == 'asc') { + search_params.set('filter', col); + search_params.set('order', ord); + wurl.search = search_params.toString(); + el.find('i').removeClass('fa-chevron-up').addClass('fa-chevron-down'); + el.data('dir', 'desc'); + } else { + search_params.set('filter', col); + search_params.set('order', ord); + wurl.search = search_params.toString(); + el.find('i').removeClass('fa-chevron-down').addClass('fa-chevron-up'); + el.data('dir', 'asc'); + } + window.location.href = wurl.toString(); + }); + + + $(document).on('click', '#row-check-all', function(e) { + return; + let el = $(this); + let attr = el.attr('checked'); + + if (typeof attr !== typeof undefined && attr !== false) { + $('tbody .user-row').removeClass('user-row-active'); + $('.bulk-actions').addClass('d-none'); + $('.row-check-item').removeAttr('checked').prop('checked', false); + el.removeAttr('checked').prop('checked', false); + } else { + $('tbody .user-row').addClass('user-row-active'); + $('.bulk-actions').removeClass('d-none'); + el.attr('checked', '').prop('checked', true); + $('.row-check-item').attr('checked', '').prop('checked', true); + } + + let len = $('.row-check-item:checked').length; + if(attr == true) { + len--; + } + $('.bulk-count').text(len).attr('data-count', len); + }); + + + $(document).on('click', '.row-check-item', function(e) { + return; + var el = $(this)[0]; + let len = $('.row-check-item:checked').length; + if($('#row-check-all:checked').length > 0) { + len--; + } + if($(this).hasClass('row-check-all')) { + return; + }; + if(el.checked == true) { + $(this).parents().eq(2).addClass('user-row-active'); + $('.bulk-actions').removeClass('d-none'); + $('.bulk-count').text(len).attr('data-count', len); + } else { + $(this).parents().eq(2).removeClass('user-row-active'); + if(len == 0) { + $('.bulk-actions').addClass('d-none'); + } else { + $('.bulk-count').text(len).attr('data-count', len); + } + } + if(len == 0) { + $('.bulk-actions').addClass('d-none'); + $('#row-check-all').prop('checked', false); + } else { + $('.bulk-actions').removeClass('d-none'); + } + }); + + $(document).on('click', '.apply-bulk', function(e) { + return; + e.preventDefault(); + let len = $('.row-check-item:checked').length; + if($('#row-check-all:checked').length > 0) { + len--; + } + if(len == 0) { + return; + } + let action = $('.bulk-action').val(); + let ids = $('.row-check-item:checked').get().filter(i => { + let el = $(i); + if(el.hasClass('row-check-all')) { + return false; + } + return true; + }).map(i => { + return $(i).data('id'); + }); + let actions = [ + '', + 'review', + 'cw', + 'unlist', + 'noautolink', + 'suspend', + 'delete' + ]; + action = actions[action]; + if(!action) { + return; + } + swal( + 'Confirm', + 'Are you sure you want to perform this action?', + 'warning' + ).then(res => { + console.log(action); + console.log(ids); + }) + }); @endpush diff --git a/resources/views/admin/reports/home.blade.php b/resources/views/admin/reports/home.blade.php index b7099514c..569ee9d65 100644 --- a/resources/views/admin/reports/home.blade.php +++ b/resources/views/admin/reports/home.blade.php @@ -66,12 +66,10 @@ -
-
# Reporter @@ -84,14 +82,14 @@ @foreach($reports as $report) - +
- + {{$report->id}}