123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734 |
- <?php
- namespace App\Http\Controllers\Admin;
- use App\AccountInterstitial;
- use App\Http\Resources\Admin\AdminModeratedProfileResource;
- use App\Http\Resources\AdminRemoteReport;
- use App\Http\Resources\AdminReport;
- use App\Http\Resources\AdminSpamReport;
- use App\Jobs\DeletePipeline\DeleteAccountPipeline;
- use App\Jobs\DeletePipeline\DeleteRemoteProfilePipeline;
- use App\Jobs\StatusPipeline\RemoteStatusDelete;
- use App\Jobs\StatusPipeline\StatusDelete;
- use App\Jobs\StoryPipeline\StoryDelete;
- use App\Models\ModeratedProfile;
- use App\Models\RemoteReport;
- use App\Notification;
- use App\Profile;
- use App\Report;
- use App\Services\AccountService;
- use App\Services\ModLogService;
- use App\Services\NetworkTimelineService;
- use App\Services\NotificationService;
- use App\Services\PublicTimelineService;
- use App\Services\StatusService;
- use App\Status;
- use App\Story;
- use App\User;
- use App\Util\ActivityPub\Helpers;
- use Cache;
- use Carbon\Carbon;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Redis;
- use Storage;
- trait AdminReportController
- {
- public function reports(Request $request)
- {
- $filter = $request->input('filter') == 'closed' ? 'closed' : 'open';
- $page = $request->input('page') ?? 1;
- $ai = Cache::remember('admin-dash:reports:ai-count', 3600, function () {
- return AccountInterstitial::whereNotNull('appeal_requested_at')->whereNull('appeal_handled_at')->count();
- });
- $spam = Cache::remember('admin-dash:reports:spam-count', 3600, function () {
- return AccountInterstitial::whereType('post.autospam')->whereNull('appeal_handled_at')->count();
- });
- $mailVerifications = Redis::scard('email:manual');
- if ($filter == 'open' && $page == 1) {
- $reports = Cache::remember('admin-dash:reports:list-cache', 300, function () use ($filter) {
- return Report::whereHas('status')
- ->whereHas('reportedUser')
- ->whereHas('reporter')
- ->orderBy('created_at', 'desc')
- ->when($filter, function ($q, $filter) {
- return $filter == 'open' ?
- $q->whereNull('admin_seen') :
- $q->whereNotNull('admin_seen');
- })
- ->paginate(6);
- });
- } else {
- $reports = Report::whereHas('status')
- ->whereHas('reportedUser')
- ->whereHas('reporter')
- ->orderBy('created_at', 'desc')
- ->when($filter, function ($q, $filter) {
- return $filter == 'open' ?
- $q->whereNull('admin_seen') :
- $q->whereNotNull('admin_seen');
- })
- ->paginate(6);
- }
- return view('admin.reports.home', compact('reports', 'ai', 'spam', 'mailVerifications'));
- }
- public function showReport(Request $request, $id)
- {
- $report = Report::with('status')->findOrFail($id);
- if ($request->has('ref') && $request->input('ref') == 'email') {
- return redirect('/i/admin/reports?tab=report&id='.$report->id);
- }
- return view('admin.reports.show', compact('report'));
- }
- public function appeals(Request $request)
- {
- $appeals = AccountInterstitial::whereNotNull('appeal_requested_at')
- ->whereNull('appeal_handled_at')
- ->latest()
- ->paginate(6);
- return view('admin.reports.appeals', compact('appeals'));
- }
- public function showAppeal(Request $request, $id)
- {
- $appeal = AccountInterstitial::whereNotNull('appeal_requested_at')
- ->whereNull('appeal_handled_at')
- ->findOrFail($id);
- $meta = json_decode($appeal->meta);
- return view('admin.reports.show_appeal', compact('appeal', 'meta'));
- }
- public function spam(Request $request)
- {
- $this->validate($request, [
- 'tab' => 'sometimes|in:home,not-spam,spam,settings,custom,exemptions',
- ]);
- $tab = $request->input('tab', 'home');
- $openCount = Cache::remember('admin-dash:reports:spam-count', 3600, function () {
- return AccountInterstitial::whereType('post.autospam')
- ->whereNull('appeal_handled_at')
- ->count();
- });
- $monthlyCount = Cache::remember('admin-dash:reports:spam-count:30d', 43200, function () {
- return AccountInterstitial::whereType('post.autospam')
- ->where('created_at', '>', now()->subMonth())
- ->count();
- });
- $totalCount = Cache::remember('admin-dash:reports:spam-count:total', 43200, function () {
- return AccountInterstitial::whereType('post.autospam')->count();
- });
- $uncategorized = Cache::remember('admin-dash:reports:spam-sync', 3600, function () {
- return AccountInterstitial::whereType('post.autospam')
- ->whereIsSpam(null)
- ->whereNotNull('appeal_handled_at')
- ->exists();
- });
- $avg = Cache::remember('admin-dash:reports:spam-count:avg', 43200, function () {
- if (config('database.default') != 'mysql') {
- return 0;
- }
- return AccountInterstitial::selectRaw('*, count(id) as counter')
- ->whereType('post.autospam')
- ->groupBy('user_id')
- ->get()
- ->avg('counter');
- });
- $avgOpen = Cache::remember('admin-dash:reports:spam-count:avgopen', 43200, function () {
- if (config('database.default') != 'mysql') {
- return '0';
- }
- $seconds = AccountInterstitial::selectRaw('DATE(created_at) AS start_date, AVG(TIME_TO_SEC(TIMEDIFF(appeal_handled_at, created_at))) AS timediff')->whereType('post.autospam')->whereNotNull('appeal_handled_at')->where('created_at', '>', now()->subMonth())->get();
- if (! $seconds) {
- return '0';
- }
- $mins = floor($seconds->avg('timediff') / 60);
- if ($mins < 60) {
- return $mins.' min(s)';
- }
- if ($mins < 2880) {
- return floor($mins / 60).' hour(s)';
- }
- return floor($mins / 60 / 24).' day(s)';
- });
- $avgCount = $totalCount && $avg ? floor($totalCount / $avg) : '0';
- if (in_array($tab, ['home', 'spam', 'not-spam'])) {
- $appeals = AccountInterstitial::whereType('post.autospam')
- ->when($tab, function ($q, $tab) {
- switch ($tab) {
- case 'home':
- return $q->whereNull('appeal_handled_at');
- break;
- case 'spam':
- return $q->whereIsSpam(true);
- break;
- case 'not-spam':
- return $q->whereIsSpam(false);
- break;
- }
- })
- ->latest()
- ->paginate(6);
- if ($tab !== 'home') {
- $appeals = $appeals->appends(['tab' => $tab]);
- }
- } else {
- $appeals = new class
- {
- public function count()
- {
- return 0;
- }
- public function render() {}
- };
- }
- return view('admin.reports.spam', compact('tab', 'appeals', 'openCount', 'monthlyCount', 'totalCount', 'avgCount', 'avgOpen', 'uncategorized'));
- }
- public function showSpam(Request $request, $id)
- {
- $appeal = AccountInterstitial::whereType('post.autospam')
- ->findOrFail($id);
- if ($request->has('ref') && $request->input('ref') == 'email') {
- return redirect('/i/admin/reports?tab=autospam&id='.$appeal->id);
- }
- $meta = json_decode($appeal->meta);
- return view('admin.reports.show_spam', compact('appeal', 'meta'));
- }
- public function fixUncategorizedSpam(Request $request)
- {
- if (Cache::get('admin-dash:reports:spam-sync-active')) {
- return redirect('/i/admin/reports/autospam');
- }
- Cache::put('admin-dash:reports:spam-sync-active', 1, 900);
- AccountInterstitial::chunk(500, function ($reports) {
- foreach ($reports as $report) {
- if ($report->item_type != 'App\Status') {
- continue;
- }
- if ($report->type != 'post.autospam') {
- continue;
- }
- if ($report->is_spam != null) {
- continue;
- }
- $status = StatusService::get($report->item_id, false);
- if (! $status) {
- return;
- }
- $scope = $status['visibility'];
- $report->is_spam = $scope == 'unlisted';
- $report->in_violation = $report->is_spam;
- $report->severity_index = 1;
- $report->save();
- }
- });
- Cache::forget('admin-dash:reports:spam-sync');
- return redirect('/i/admin/reports/autospam');
- }
- public function updateSpam(Request $request, $id)
- {
- $this->validate($request, [
- 'action' => 'required|in:dismiss,approve,dismiss-all,approve-all,delete-account,mark-spammer',
- ]);
- $action = $request->input('action');
- $appeal = AccountInterstitial::whereType('post.autospam')
- ->whereNull('appeal_handled_at')
- ->findOrFail($id);
- $meta = json_decode($appeal->meta);
- $res = ['status' => 'success'];
- $now = now();
- Cache::forget('admin-dash:reports:spam-count:total');
- Cache::forget('admin-dash:reports:spam-count:30d');
- if ($action == 'delete-account') {
- if (config('pixelfed.account_deletion') == false) {
- abort(404);
- }
- $user = User::findOrFail($appeal->user_id);
- $profile = $user->profile;
- if ($user->is_admin == true) {
- $mid = $request->user()->id;
- abort_if($user->id < $mid, 403);
- }
- $ts = now()->addMonth();
- $user->status = 'delete';
- $profile->status = 'delete';
- $user->delete_after = $ts;
- $profile->delete_after = $ts;
- $user->save();
- $profile->save();
- ModLogService::boot()
- ->objectUid($user->id)
- ->objectId($user->id)
- ->objectType('App\User::class')
- ->user($request->user())
- ->action('admin.user.delete')
- ->accessLevel('admin')
- ->save();
- Cache::forget('profiles:private');
- DeleteAccountPipeline::dispatch($user);
- return;
- }
- if ($action == 'dismiss') {
- $appeal->is_spam = true;
- $appeal->appeal_handled_at = $now;
- $appeal->save();
- Cache::forget('pf:bouncer_v0:exemption_by_pid:'.$appeal->user->profile_id);
- Cache::forget('pf:bouncer_v0:recent_by_pid:'.$appeal->user->profile_id);
- Cache::forget('admin-dash:reports:spam-count');
- return $res;
- }
- if ($action == 'dismiss-all') {
- AccountInterstitial::whereType('post.autospam')
- ->whereItemType('App\Status')
- ->whereNull('appeal_handled_at')
- ->whereUserId($appeal->user_id)
- ->update(['appeal_handled_at' => $now, 'is_spam' => true]);
- Cache::forget('pf:bouncer_v0:exemption_by_pid:'.$appeal->user->profile_id);
- Cache::forget('pf:bouncer_v0:recent_by_pid:'.$appeal->user->profile_id);
- Cache::forget('admin-dash:reports:spam-count');
- return $res;
- }
- if ($action == 'approve-all') {
- AccountInterstitial::whereType('post.autospam')
- ->whereItemType('App\Status')
- ->whereNull('appeal_handled_at')
- ->whereUserId($appeal->user_id)
- ->get()
- ->each(function ($report) use ($meta) {
- $report->is_spam = false;
- $report->appeal_handled_at = now();
- $report->save();
- $status = Status::find($report->item_id);
- if ($status) {
- $status->is_nsfw = $meta->is_nsfw;
- $status->scope = 'public';
- $status->visibility = 'public';
- $status->save();
- StatusService::del($status->id, true);
- }
- });
- Cache::forget('pf:bouncer_v0:exemption_by_pid:'.$appeal->user->profile_id);
- Cache::forget('pf:bouncer_v0:recent_by_pid:'.$appeal->user->profile_id);
- Cache::forget('admin-dash:reports:spam-count');
- return $res;
- }
- if ($action == 'mark-spammer') {
- AccountInterstitial::whereType('post.autospam')
- ->whereItemType('App\Status')
- ->whereNull('appeal_handled_at')
- ->whereUserId($appeal->user_id)
- ->update(['appeal_handled_at' => $now, 'is_spam' => true]);
- $pro = Profile::whereUserId($appeal->user_id)->firstOrFail();
- $pro->update([
- 'unlisted' => true,
- 'cw' => true,
- 'no_autolink' => true,
- ]);
- Status::whereProfileId($pro->id)
- ->get()
- ->each(function ($report) {
- $status->is_nsfw = $meta->is_nsfw;
- $status->scope = 'public';
- $status->visibility = 'public';
- $status->save();
- StatusService::del($status->id, true);
- });
- Cache::forget('pf:bouncer_v0:exemption_by_pid:'.$appeal->user->profile_id);
- Cache::forget('pf:bouncer_v0:recent_by_pid:'.$appeal->user->profile_id);
- Cache::forget('admin-dash:reports:spam-count');
- return $res;
- }
- $status = $appeal->status;
- $status->is_nsfw = $meta->is_nsfw;
- $status->scope = 'public';
- $status->visibility = 'public';
- $status->save();
- $appeal->is_spam = false;
- $appeal->appeal_handled_at = now();
- $appeal->save();
- StatusService::del($status->id);
- Cache::forget('pf:bouncer_v0:exemption_by_pid:'.$appeal->user->profile_id);
- Cache::forget('pf:bouncer_v0:recent_by_pid:'.$appeal->user->profile_id);
- Cache::forget('admin-dash:reports:spam-count');
- return $res;
- }
- public function updateAppeal(Request $request, $id)
- {
- $this->validate($request, [
- 'action' => 'required|in:dismiss,approve',
- ]);
- $action = $request->input('action');
- $appeal = AccountInterstitial::whereNotNull('appeal_requested_at')
- ->whereNull('appeal_handled_at')
- ->findOrFail($id);
- if ($action == 'dismiss') {
- $appeal->appeal_handled_at = now();
- $appeal->save();
- Cache::forget('admin-dash:reports:ai-count');
- return redirect('/i/admin/reports/appeals');
- }
- switch ($appeal->type) {
- case 'post.cw':
- $status = $appeal->status;
- $status->is_nsfw = false;
- $status->save();
- break;
- case 'post.unlist':
- $status = $appeal->status;
- $status->scope = 'public';
- $status->visibility = 'public';
- $status->save();
- break;
- default:
- // code...
- break;
- }
- $appeal->appeal_handled_at = now();
- $appeal->save();
- StatusService::del($status->id, true);
- Cache::forget('admin-dash:reports:ai-count');
- return redirect('/i/admin/reports/appeals');
- }
- public function updateReport(Request $request, $id)
- {
- $this->validate($request, [
- 'action' => 'required|string',
- ]);
- $action = $request->input('action');
- $actions = [
- 'ignore',
- 'cw',
- 'unlist',
- 'delete',
- 'shadowban',
- 'ban',
- ];
- if (! in_array($action, $actions)) {
- return abort(403);
- }
- $report = Report::findOrFail($id);
- $this->handleReportAction($report, $action);
- Cache::forget('admin-dash:reports:list-cache');
- return response()->json(['msg' => 'Success']);
- }
- public function handleReportAction(Report $report, $action)
- {
- $item = $report->reported();
- $report->admin_seen = Carbon::now();
- switch ($action) {
- case 'ignore':
- $report->not_interested = true;
- break;
- case 'cw':
- Cache::forget('status:thumb:'.$item->id);
- $item->is_nsfw = true;
- $item->save();
- $report->nsfw = true;
- StatusService::del($item->id, true);
- break;
- case 'unlist':
- $item->visibility = 'unlisted';
- $item->save();
- Cache::forget('profiles:private');
- StatusService::del($item->id, true);
- break;
- case 'delete':
- // Todo: fire delete job
- $report->admin_seen = null;
- StatusService::del($item->id, true);
- break;
- case 'shadowban':
- // Todo: fire delete job
- $report->admin_seen = null;
- break;
- case 'ban':
- // Todo: fire delete job
- $report->admin_seen = null;
- break;
- default:
- $report->admin_seen = null;
- break;
- }
- $report->save();
- return $this;
- }
- protected function actionMap()
- {
- return [
- '1' => 'ignore',
- '2' => 'cw',
- '3' => 'unlist',
- '4' => 'delete',
- '5' => 'shadowban',
- '6' => 'ban',
- ];
- }
- public function bulkUpdateReport(Request $request)
- {
- $this->validate($request, [
- 'action' => 'required|integer|min:1|max:10',
- 'ids' => 'required|array',
- ]);
- $action = $this->actionMap()[$request->input('action')];
- $ids = $request->input('ids');
- $reports = Report::whereIn('id', $ids)->whereNull('admin_seen')->get();
- foreach ($reports as $report) {
- $this->handleReportAction($report, $action);
- }
- $res = [
- 'message' => 'Success',
- 'code' => 200,
- ];
- return response()->json($res);
- }
- public function reportMailVerifications(Request $request)
- {
- $ids = Redis::smembers('email:manual');
- $ignored = Redis::smembers('email:manual-ignored');
- $reports = [];
- if ($ids) {
- $reports = collect($ids)
- ->filter(function ($id) use ($ignored) {
- return ! in_array($id, $ignored);
- })
- ->map(function ($id) {
- $user = User::whereProfileId($id)->first();
- if (! $user || $user->email_verified_at) {
- return [];
- }
- $account = AccountService::get($id, true);
- if (! $account) {
- return [];
- }
- $account['email'] = $user->email;
- return $account;
- })
- ->filter(function ($res) {
- return $res && isset($res['id']);
- })
- ->values();
- }
- return view('admin.reports.mail_verification', compact('reports', 'ignored'));
- }
- public function reportMailVerifyIgnore(Request $request)
- {
- $id = $request->input('id');
- Redis::sadd('email:manual-ignored', $id);
- return redirect('/i/admin/reports');
- }
- public function reportMailVerifyApprove(Request $request)
- {
- $id = $request->input('id');
- $user = User::whereProfileId($id)->firstOrFail();
- Redis::srem('email:manual', $id);
- Redis::srem('email:manual-ignored', $id);
- $user->email_verified_at = now();
- $user->save();
- return redirect('/i/admin/reports');
- }
- public function reportMailVerifyClearIgnored(Request $request)
- {
- Redis::del('email:manual-ignored');
- return [200];
- }
- public function reportsStats(Request $request)
- {
- $stats = [
- 'total' => Report::count(),
- 'open' => Report::whereNull('admin_seen')->count(),
- 'closed' => Report::whereNotNull('admin_seen')->count(),
- 'autospam' => AccountInterstitial::whereType('post.autospam')->count(),
- 'autospam_open' => AccountInterstitial::whereType('post.autospam')->whereNull(['appeal_handled_at'])->count(),
- 'appeals' => AccountInterstitial::whereNotNull('appeal_requested_at')->whereNull('appeal_handled_at')->count(),
- 'remote_open' => RemoteReport::whereNull('action_taken_at')->count(),
- 'email_verification_requests' => Redis::scard('email:manual'),
- ];
- return $stats;
- }
- public function reportsApiAll(Request $request)
- {
- $filter = $request->input('filter') == 'closed' ? 'closed' : 'open';
- $reports = AdminReport::collection(
- Report::orderBy('id', 'desc')
- ->when($filter, function ($q, $filter) {
- return $filter == 'open' ?
- $q->whereNull('admin_seen') :
- $q->whereNotNull('admin_seen');
- })
- ->groupBy(['id', 'object_id', 'object_type', 'profile_id'])
- ->cursorPaginate(6)
- ->withQueryString()
- );
- return $reports;
- }
- public function reportsApiRemote(Request $request)
- {
- $filter = $request->input('filter') == 'closed' ? 'closed' : 'open';
- $reports = AdminRemoteReport::collection(
- RemoteReport::orderBy('id', 'desc')
- ->when($filter, function ($q, $filter) {
- return $filter == 'open' ?
- $q->whereNull('action_taken_at') :
- $q->whereNotNull('action_taken_at');
- })
- ->cursorPaginate(6)
- ->withQueryString()
- );
- return $reports;
- }
- public function reportsApiGet(Request $request, $id)
- {
- $report = Report::findOrFail($id);
- return new AdminReport($report);
- }
- public function reportsApiHandle(Request $request)
- {
- $this->validate($request, [
- 'object_id' => 'required',
- 'object_type' => 'required',
- 'id' => 'required',
- 'action' => 'required|in:ignore,nsfw,unlist,private,delete,delete-all',
- 'action_type' => 'required|in:post,profile,story',
- ]);
- $report = Report::whereObjectId($request->input('object_id'))->findOrFail($request->input('id'));
- if ($request->input('action_type') === 'profile') {
- return $this->reportsHandleProfileAction($report, $request->input('action'));
- } elseif ($request->input('action_type') === 'post') {
- return $this->reportsHandleStatusAction($report, $request->input('action'));
- } elseif ($request->input('action_type') === 'story') {
- return $this->reportsHandleStoryAction($report, $request->input('action'));
- }
- return $report;
- }
- protected function reportsHandleStoryAction($report, $action)
- {
- switch ($action) {
- case 'ignore':
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'delete':
- $profile = Profile::find($report->reported_profile_id);
- $story = Story::whereProfileId($profile->id)->find($report->object_id);
- abort_if(! $story, 400, 'Invalid or missing story');
- $story->active = false;
- $story->save();
- ModLogService::boot()
- ->objectUid($profile->id)
- ->objectId($report->object_id)
- ->objectType('App\Story::class')
- ->user(request()->user())
- ->action('admin.user.moderate')
- ->metadata([
- 'action' => 'delete',
- 'message' => 'Success!',
- ])
- ->accessLevel('admin')
- ->save();
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- StoryDelete::dispatch($story)->onQueue('story');
- return [200];
- break;
- case 'delete-all':
- $profile = Profile::find($report->reported_profile_id);
- $stories = Story::whereProfileId($profile->id)->whereActive(true)->get();
- abort_if(! $stories || ! $stories->count(), 400, 'Invalid or missing stories');
- ModLogService::boot()
- ->objectUid($profile->id)
- ->objectId($report->object_id)
- ->objectType('App\Story::class')
- ->user(request()->user())
- ->action('admin.user.moderate')
- ->metadata([
- 'action' => 'delete-all',
- 'message' => 'Success!',
- ])
- ->accessLevel('admin')
- ->save();
- Report::where('reported_profile_id', $profile->id)
- ->whereObjectType('App\Story')
- ->whereNull('admin_seen')
- ->update([
- 'admin_seen' => now(),
- ]);
- $stories->each(function ($story) {
- StoryDelete::dispatch($story)->onQueue('story');
- });
- return [200];
- break;
- }
- }
- protected function reportsHandleProfileAction($report, $action)
- {
- switch ($action) {
- case 'ignore':
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'nsfw':
- if ($report->object_type === 'App\Profile') {
- $profile = Profile::find($report->object_id);
- } elseif ($report->object_type === 'App\Status') {
- $status = Status::find($report->object_id);
- if (! $status) {
- return [200];
- }
- $profile = Profile::find($status->profile_id);
- }
- if (! $profile) {
- return;
- }
- abort_if($profile->user && $profile->user->is_admin, 400, 'Cannot moderate an admin account.');
- $profile->cw = true;
- $profile->save();
- if ($profile->remote_url) {
- ModeratedProfile::updateOrCreate([
- 'profile_url' => $profile->remote_url,
- 'profile_id' => $profile->id,
- ], [
- 'is_nsfw' => true,
- 'domain' => $profile->domain,
- ]);
- }
- foreach (Status::whereProfileId($profile->id)->cursor() as $status) {
- $status->is_nsfw = true;
- $status->save();
- StatusService::del($status->id);
- PublicTimelineService::rem($status->id);
- }
- ModLogService::boot()
- ->objectUid($profile->id)
- ->objectId($profile->id)
- ->objectType('App\Profile::class')
- ->user(request()->user())
- ->action('admin.user.moderate')
- ->metadata([
- 'action' => 'cw',
- 'message' => 'Success!',
- ])
- ->accessLevel('admin')
- ->save();
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'nsfw' => true,
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'unlist':
- if ($report->object_type === 'App\Profile') {
- $profile = Profile::find($report->object_id);
- } elseif ($report->object_type === 'App\Status') {
- $status = Status::find($report->object_id);
- if (! $status) {
- return [200];
- }
- $profile = Profile::find($status->profile_id);
- }
- if (! $profile) {
- return;
- }
- abort_if($profile->user && $profile->user->is_admin, 400, 'Cannot moderate an admin account.');
- $profile->unlisted = true;
- $profile->save();
- if ($profile->remote_url) {
- ModeratedProfile::updateOrCreate([
- 'profile_url' => $profile->remote_url,
- 'profile_id' => $profile->id,
- ], [
- 'is_unlisted' => true,
- 'domain' => $profile->domain,
- ]);
- }
- foreach (Status::whereProfileId($profile->id)->whereScope('public')->cursor() as $status) {
- $status->scope = 'unlisted';
- $status->visibility = 'unlisted';
- $status->save();
- StatusService::del($status->id);
- PublicTimelineService::rem($status->id);
- }
- ModLogService::boot()
- ->objectUid($profile->id)
- ->objectId($profile->id)
- ->objectType('App\Profile::class')
- ->user(request()->user())
- ->action('admin.user.moderate')
- ->metadata([
- 'action' => 'unlisted',
- 'message' => 'Success!',
- ])
- ->accessLevel('admin')
- ->save();
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'private':
- if ($report->object_type === 'App\Profile') {
- $profile = Profile::find($report->object_id);
- } elseif ($report->object_type === 'App\Status') {
- $status = Status::find($report->object_id);
- if (! $status) {
- return [200];
- }
- $profile = Profile::find($status->profile_id);
- }
- if (! $profile) {
- return;
- }
- abort_if($profile->user && $profile->user->is_admin, 400, 'Cannot moderate an admin account.');
- $profile->unlisted = true;
- $profile->save();
- if ($profile->remote_url) {
- ModeratedProfile::updateOrCreate([
- 'profile_url' => $profile->remote_url,
- 'profile_id' => $profile->id,
- ], [
- 'is_unlisted' => true,
- 'domain' => $profile->domain,
- ]);
- }
- foreach (Status::whereProfileId($profile->id)->cursor() as $status) {
- $status->scope = 'private';
- $status->visibility = 'private';
- $status->save();
- StatusService::del($status->id);
- PublicTimelineService::rem($status->id);
- }
- ModLogService::boot()
- ->objectUid($profile->id)
- ->objectId($profile->id)
- ->objectType('App\Profile::class')
- ->user(request()->user())
- ->action('admin.user.moderate')
- ->metadata([
- 'action' => 'private',
- 'message' => 'Success!',
- ])
- ->accessLevel('admin')
- ->save();
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'delete':
- if (config('pixelfed.account_deletion') == false) {
- abort(404);
- }
- if ($report->object_type === 'App\Profile') {
- $profile = Profile::find($report->object_id);
- } elseif ($report->object_type === 'App\Status') {
- $status = Status::find($report->object_id);
- if (! $status) {
- return [200];
- }
- $profile = Profile::find($status->profile_id);
- }
- if (! $profile) {
- return;
- }
- abort_if($profile->user && $profile->user->is_admin, 400, 'Cannot delete an admin account.');
- $ts = now()->addMonth();
- if ($profile->remote_url) {
- ModeratedProfile::updateOrCreate([
- 'profile_url' => $profile->remote_url,
- 'profile_id' => $profile->id,
- ], [
- 'is_banned' => true,
- 'domain' => $profile->domain,
- ]);
- }
- if ($profile->user_id) {
- $user = $profile->user;
- abort_if($user->is_admin, 403, 'You cannot delete admin accounts.');
- $user->status = 'delete';
- $user->delete_after = $ts;
- $user->save();
- }
- $profile->status = 'delete';
- $profile->delete_after = $ts;
- $profile->save();
- ModLogService::boot()
- ->objectUid($profile->id)
- ->objectId($profile->id)
- ->objectType('App\Profile::class')
- ->user(request()->user())
- ->action('admin.user.delete')
- ->accessLevel('admin')
- ->save();
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- if ($profile->user_id) {
- DB::table('oauth_access_tokens')->whereUserId($user->id)->delete();
- DB::table('oauth_auth_codes')->whereUserId($user->id)->delete();
- $user->email = $user->id;
- $user->password = '';
- $user->status = 'delete';
- $user->save();
- $profile->status = 'delete';
- $profile->delete_after = now()->addMonth();
- $profile->save();
- AccountService::del($profile->id);
- DeleteAccountPipeline::dispatch($user)->onQueue('high');
- } else {
- $profile->status = 'delete';
- $profile->delete_after = now()->addMonth();
- $profile->save();
- AccountService::del($profile->id);
- DeleteRemoteProfilePipeline::dispatch($profile)->onQueue('high');
- }
- return [200];
- break;
- }
- }
- protected function reportsHandleStatusAction($report, $action)
- {
- switch ($action) {
- case 'ignore':
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'nsfw':
- $status = Status::find($report->object_id);
- if (! $status) {
- return [200];
- }
- abort_if($status->profile->user && $status->profile->user->is_admin, 400, 'Cannot moderate an admin account post.');
- $status->is_nsfw = true;
- $status->save();
- StatusService::del($status->id);
- ModLogService::boot()
- ->objectUid($status->profile_id)
- ->objectId($status->profile_id)
- ->objectType('App\Status::class')
- ->user(request()->user())
- ->action('admin.status.moderate')
- ->metadata([
- 'action' => 'cw',
- 'message' => 'Success!',
- ])
- ->accessLevel('admin')
- ->save();
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'nsfw' => true,
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'private':
- $status = Status::find($report->object_id);
- if (! $status) {
- return [200];
- }
- abort_if($status->profile->user && $status->profile->user->is_admin, 400, 'Cannot moderate an admin account post.');
- $status->scope = 'private';
- $status->visibility = 'private';
- $status->save();
- StatusService::del($status->id);
- PublicTimelineService::rem($status->id);
- ModLogService::boot()
- ->objectUid($status->profile_id)
- ->objectId($status->profile_id)
- ->objectType('App\Status::class')
- ->user(request()->user())
- ->action('admin.status.moderate')
- ->metadata([
- 'action' => 'private',
- 'message' => 'Success!',
- ])
- ->accessLevel('admin')
- ->save();
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'unlist':
- $status = Status::find($report->object_id);
- if (! $status) {
- return [200];
- }
- abort_if($status->profile->user && $status->profile->user->is_admin, 400, 'Cannot moderate an admin account post.');
- if ($status->scope === 'public') {
- $status->scope = 'unlisted';
- $status->visibility = 'unlisted';
- $status->save();
- StatusService::del($status->id);
- PublicTimelineService::rem($status->id);
- }
- ModLogService::boot()
- ->objectUid($status->profile_id)
- ->objectId($status->profile_id)
- ->objectType('App\Status::class')
- ->user(request()->user())
- ->action('admin.status.moderate')
- ->metadata([
- 'action' => 'unlist',
- 'message' => 'Success!',
- ])
- ->accessLevel('admin')
- ->save();
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- case 'delete':
- $status = Status::find($report->object_id);
- if (! $status) {
- return [200];
- }
- $profile = $status->profile;
- abort_if($profile->user && $profile->user->is_admin, 400, 'Cannot delete an admin account post.');
- StatusService::del($status->id);
- if ($profile->user_id != null && $profile->domain == null) {
- PublicTimelineService::del($status->id);
- StatusDelete::dispatch($status)->onQueue('high');
- } else {
- NetworkTimelineService::del($status->id);
- RemoteStatusDelete::dispatch($status)->onQueue('high');
- }
- Report::whereObjectId($report->object_id)
- ->whereObjectType($report->object_type)
- ->update([
- 'admin_seen' => now(),
- ]);
- return [200];
- break;
- }
- }
- public function reportsApiSpamAll(Request $request)
- {
- $tab = $request->input('tab', 'home');
- $appeals = AdminSpamReport::collection(
- AccountInterstitial::orderBy('id', 'desc')
- ->whereType('post.autospam')
- ->whereNull('appeal_handled_at')
- ->cursorPaginate(6)
- ->withQueryString()
- );
- return $appeals;
- }
- public function reportsApiSpamHandle(Request $request)
- {
- $this->validate($request, [
- 'id' => 'required',
- 'action' => 'required|in:mark-read,mark-not-spam,mark-all-read,mark-all-not-spam,delete-profile',
- ]);
- $action = $request->input('action');
- abort_if(
- $action === 'delete-profile' &&
- ! config('pixelfed.account_deletion'),
- 404,
- "Cannot delete profile, account_deletion is disabled.\n\n Set `ACCOUNT_DELETION=true` in .env and re-cache config."
- );
- $report = AccountInterstitial::with('user')
- ->whereType('post.autospam')
- ->whereNull('appeal_handled_at')
- ->findOrFail($request->input('id'));
- $this->reportsHandleSpamAction($report, $action);
- Cache::forget('admin-dash:reports:spam-count');
- Cache::forget('pf:bouncer_v0:exemption_by_pid:'.$report->user->profile_id);
- Cache::forget('pf:bouncer_v0:recent_by_pid:'.$report->user->profile_id);
- return [$action, $report];
- }
- public function reportsHandleSpamAction($appeal, $action)
- {
- $meta = json_decode($appeal->meta);
- if ($action == 'mark-read') {
- $appeal->is_spam = true;
- $appeal->appeal_handled_at = now();
- $appeal->save();
- PublicTimelineService::del($appeal->item_id);
- }
- if ($action == 'mark-not-spam') {
- $status = $appeal->status;
- $status->is_nsfw = $meta->is_nsfw;
- $status->scope = 'public';
- $status->visibility = 'public';
- $status->save();
- $appeal->is_spam = false;
- $appeal->appeal_handled_at = now();
- $appeal->save();
- Notification::whereAction('autospam.warning')
- ->whereProfileId($appeal->user->profile_id)
- ->get()
- ->each(function ($n) use ($appeal) {
- NotificationService::del($appeal->user->profile_id, $n->id);
- $n->forceDelete();
- });
- StatusService::del($status->id);
- StatusService::get($status->id);
- if ($status->in_reply_to_id == null && $status->reblog_of_id == null) {
- PublicTimelineService::add($status->id);
- }
- }
- if ($action == 'mark-all-read') {
- AccountInterstitial::whereType('post.autospam')
- ->whereItemType('App\Status')
- ->whereNull('appeal_handled_at')
- ->whereUserId($appeal->user_id)
- ->update([
- 'appeal_handled_at' => now(),
- 'is_spam' => true,
- ]);
- }
- if ($action == 'mark-all-not-spam') {
- AccountInterstitial::whereType('post.autospam')
- ->whereItemType('App\Status')
- ->whereUserId($appeal->user_id)
- ->get()
- ->each(function ($report) use ($meta) {
- $report->is_spam = false;
- $report->appeal_handled_at = now();
- $report->save();
- $status = Status::find($report->item_id);
- if ($status) {
- $status->is_nsfw = $meta->is_nsfw;
- $status->scope = 'public';
- $status->visibility = 'public';
- $status->save();
- StatusService::del($status->id);
- }
- Notification::whereAction('autospam.warning')
- ->whereProfileId($report->user->profile_id)
- ->get()
- ->each(function ($n) use ($report) {
- NotificationService::del($report->user->profile_id, $n->id);
- $n->forceDelete();
- });
- });
- }
- if ($action == 'delete-profile') {
- $user = User::findOrFail($appeal->user_id);
- $profile = $user->profile;
- if ($user->is_admin == true) {
- $mid = request()->user()->id;
- abort_if($user->id < $mid, 403, 'You cannot delete an admin account.');
- }
- $ts = now()->addMonth();
- $user->status = 'delete';
- $profile->status = 'delete';
- $user->delete_after = $ts;
- $profile->delete_after = $ts;
- $user->save();
- $profile->save();
- $appeal->appeal_handled_at = now();
- $appeal->save();
- ModLogService::boot()
- ->objectUid($user->id)
- ->objectId($user->id)
- ->objectType('App\User::class')
- ->user(request()->user())
- ->action('admin.user.delete')
- ->accessLevel('admin')
- ->save();
- Cache::forget('profiles:private');
- DeleteAccountPipeline::dispatch($user);
- }
- }
- public function reportsApiSpamGet(Request $request, $id)
- {
- $report = AccountInterstitial::findOrFail($id);
- return new AdminSpamReport($report);
- }
- public function reportsApiRemoteHandle(Request $request)
- {
- $this->validate($request, [
- 'id' => 'required|exists:remote_reports,id',
- 'action' => 'required|in:mark-read,cw-posts,unlist-posts,delete-posts,private-posts,mark-all-read-by-domain,mark-all-read-by-username,cw-all-posts,private-all-posts,unlist-all-posts',
- ]);
- $report = RemoteReport::findOrFail($request->input('id'));
- $user = User::whereProfileId($report->account_id)->first();
- $ogPublicStatuses = [];
- $ogUnlistedStatuses = [];
- $ogNonCwStatuses = [];
- switch ($request->input('action')) {
- case 'mark-read':
- $report->action_taken_at = now();
- $report->save();
- break;
- case 'mark-all-read-by-domain':
- RemoteReport::whereInstanceId($report->instance_id)->update(['action_taken_at' => now()]);
- break;
- case 'cw-posts':
- $statuses = Status::find($report->status_ids);
- foreach ($statuses as $status) {
- if ($report->account_id != $status->profile_id) {
- continue;
- }
- if (! $status->is_nsfw) {
- $ogNonCwStatuses[] = $status->id;
- }
- $status->is_nsfw = true;
- $status->saveQuietly();
- StatusService::del($status->id);
- }
- $report->action_taken_at = now();
- $report->save();
- break;
- case 'cw-all-posts':
- foreach (Status::whereProfileId($report->account_id)->lazyById(50, 'id') as $status) {
- if ($status->is_nsfw || $status->reblog_of_id) {
- continue;
- }
- if (! $status->is_nsfw) {
- $ogNonCwStatuses[] = $status->id;
- }
- $status->is_nsfw = true;
- $status->saveQuietly();
- StatusService::del($status->id);
- }
- break;
- case 'unlist-posts':
- $statuses = Status::find($report->status_ids);
- foreach ($statuses as $status) {
- if ($report->account_id != $status->profile_id) {
- continue;
- }
- if ($status->scope === 'public') {
- $ogPublicStatuses[] = $status->id;
- $status->scope = 'unlisted';
- $status->visibility = 'unlisted';
- $status->saveQuietly();
- StatusService::del($status->id);
- }
- }
- $report->action_taken_at = now();
- $report->save();
- break;
- case 'unlist-all-posts':
- foreach (Status::whereProfileId($report->account_id)->lazyById(50, 'id') as $status) {
- if ($status->visibility !== 'public' || $status->reblog_of_id) {
- continue;
- }
- $ogPublicStatuses[] = $status->id;
- $status->visibility = 'unlisted';
- $status->scope = 'unlisted';
- $status->saveQuietly();
- StatusService::del($status->id);
- }
- break;
- case 'private-posts':
- $statuses = Status::find($report->status_ids);
- foreach ($statuses as $status) {
- if ($report->account_id != $status->profile_id) {
- continue;
- }
- if (in_array($status->scope, ['public', 'unlisted', 'private'])) {
- if ($status->scope === 'public') {
- $ogPublicStatuses[] = $status->id;
- }
- $status->scope = 'private';
- $status->visibility = 'private';
- $status->saveQuietly();
- StatusService::del($status->id);
- }
- }
- $report->action_taken_at = now();
- $report->save();
- break;
- case 'private-all-posts':
- foreach (Status::whereProfileId($report->account_id)->lazyById(50, 'id') as $status) {
- if (! in_array($status->visibility, ['public', 'unlisted']) || $status->reblog_of_id) {
- continue;
- }
- if ($status->visibility === 'public') {
- $ogPublicStatuses[] = $status->id;
- } elseif ($status->visibility === 'unlisted') {
- $ogUnlistedStatuses[] = $status->id;
- }
- $status->visibility = 'private';
- $status->scope = 'private';
- $status->saveQuietly();
- StatusService::del($status->id);
- }
- break;
- case 'delete-posts':
- $statuses = Status::find($report->status_ids);
- foreach ($statuses as $status) {
- if ($report->account_id != $status->profile_id) {
- continue;
- }
- StatusDelete::dispatch($status);
- }
- $report->action_taken_at = now();
- $report->save();
- break;
- case 'mark-all-read-by-username':
- RemoteReport::whereNull('action_taken_at')->whereAccountId($report->account_id)->update(['action_taken_at' => now()]);
- break;
- default:
- abort(404);
- break;
- }
- if ($ogPublicStatuses && count($ogPublicStatuses)) {
- Storage::disk('local')->put('mod-log-cache/'.$report->account_id.'/'.now()->format('Y-m-d').'-og-public-statuses.json', json_encode($ogPublicStatuses, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
- }
- if ($ogNonCwStatuses && count($ogNonCwStatuses)) {
- Storage::disk('local')->put('mod-log-cache/'.$report->account_id.'/'.now()->format('Y-m-d').'-og-noncw-statuses.json', json_encode($ogNonCwStatuses, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
- }
- if ($ogUnlistedStatuses && count($ogUnlistedStatuses)) {
- Storage::disk('local')->put('mod-log-cache/'.$report->account_id.'/'.now()->format('Y-m-d').'-og-unlisted-statuses.json', json_encode($ogUnlistedStatuses, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
- }
- ModLogService::boot()
- ->user(request()->user())
- ->objectUid($user ? $user->id : null)
- ->objectId($report->id)
- ->objectType('App\Report::class')
- ->action('admin.report.moderate')
- ->metadata([
- 'action' => $request->input('action'),
- 'duration_active' => now()->parse($report->created_at)->diffForHumans(),
- ])
- ->accessLevel('admin')
- ->save();
- if ($report->status_ids) {
- foreach ($report->status_ids as $sid) {
- RemoteReport::whereNull('action_taken_at')
- ->whereJsonContains('status_ids', [$sid])
- ->update(['action_taken_at' => now()]);
- }
- }
- return [200];
- }
- public function getModeratedProfiles(Request $request)
- {
- $this->validate($request, [
- 'search' => 'sometimes|string|min:3|max:120',
- ]);
- if ($request->filled('search')) {
- $query = '%'.$request->input('search').'%';
- $profiles = DB::table('moderated_profiles')
- ->join('profiles', 'moderated_profiles.profile_id', '=', 'profiles.id')
- ->where('profiles.username', 'LIKE', $query)
- ->select('moderated_profiles.*', 'profiles.username')
- ->orderByDesc('moderated_profiles.id')
- ->cursorPaginate(5);
- return AdminModeratedProfileResource::collection($profiles);
- }
- $profiles = ModeratedProfile::orderByDesc('id')->cursorPaginate(10);
- return AdminModeratedProfileResource::collection($profiles);
- }
- public function getModeratedProfile(Request $request)
- {
- $this->validate($request, [
- 'id' => 'required',
- ]);
- $profile = ModeratedProfile::findOrFail($request->input('id'));
- return new AdminModeratedProfileResource($profile);
- }
- public function deleteModeratedProfile(Request $request)
- {
- $this->validate($request, [
- 'id' => 'required',
- ]);
- $profile = ModeratedProfile::findOrFail($request->input('id'));
- ModLogService::boot()
- ->objectUid($profile->profile_id)
- ->objectId($profile->id)
- ->objectType('App\Models\ModeratedProfile::class')
- ->user(request()->user())
- ->action('admin.moderated-profiles.delete')
- ->metadata([
- 'profile_url' => $profile->profile_url,
- 'profile_id' => $profile->profile_id,
- 'domain' => $profile->domain,
- 'note' => $profile->note,
- 'is_banned' => $profile->is_banned,
- 'is_nsfw' => $profile->is_nsfw,
- 'is_unlisted' => $profile->is_unlisted,
- 'is_noautolink' => $profile->is_noautolink,
- 'is_nodms' => $profile->is_nodms,
- 'is_notrending' => $profile->is_notrending,
- ])
- ->accessLevel('admin')
- ->save();
- $profile->delete();
- return ['status' => 200, 'message' => 'Successfully deleted moderated profile!'];
- }
- public function updateModeratedProfile(Request $request)
- {
- $this->validate($request, [
- 'id' => 'required|exists:moderated_profiles',
- 'note' => 'sometimes|nullable|string|max:500',
- 'is_banned' => 'required|boolean',
- 'is_noautolink' => 'required|boolean',
- 'is_nodms' => 'required|boolean',
- 'is_notrending' => 'required|boolean',
- 'is_nsfw' => 'required|boolean',
- 'is_unlisted' => 'required|boolean',
- ]);
- $fields = [
- 'note',
- 'is_banned',
- 'is_noautolink',
- 'is_nodms',
- 'is_notrending',
- 'is_nsfw',
- 'is_unlisted',
- ];
- $profile = ModeratedProfile::findOrFail($request->input('id'));
- $profile->update($request->only($fields));
- ModLogService::boot()
- ->objectUid($profile->profile_id)
- ->objectId($profile->id)
- ->objectType('App\Models\ModeratedProfile::class')
- ->user(request()->user())
- ->action('admin.moderated-profiles.update')
- ->metadata($request->only($fields))
- ->accessLevel('admin')
- ->save();
- return [200];
- }
- public function createModeratedProfile(Request $request)
- {
- $this->validate($request, [
- 'url' => 'required|url|starts_with:https://',
- ]);
- $url = $request->input('url');
- $host = parse_url($url, PHP_URL_HOST);
- abort_if($host === config('pixelfed.domain.app'), 400, 'You cannot add local users!');
- $exists = ModeratedProfile::whereProfileUrl($url)->exists();
- abort_if($exists, 400, 'Moderated profile already exists!');
- $profile = Profile::whereRemoteUrl($url)->first();
- if ($profile) {
- $rec = ModeratedProfile::updateOrCreate([
- 'profile_id' => $profile->id,
- ], [
- 'profile_url' => $profile->remote_url,
- 'domain' => $profile->domain,
- ]);
- ModLogService::boot()
- ->objectUid($rec->profile_id)
- ->objectId($rec->id)
- ->objectType('App\Models\ModeratedProfile::class')
- ->user(request()->user())
- ->action('admin.moderated-profiles.create')
- ->metadata([
- 'profile_existed' => true,
- ])
- ->accessLevel('admin')
- ->save();
- return $rec;
- }
- $remoteSearch = Helpers::profileFetch($url);
- if ($remoteSearch) {
- $rec = ModeratedProfile::updateOrCreate([
- 'profile_id' => $remoteSearch->id,
- ], [
- 'profile_url' => $remoteSearch->remote_url,
- 'domain' => $remoteSearch->domain,
- ]);
- ModLogService::boot()
- ->objectUid($rec->profile_id)
- ->objectId($rec->id)
- ->objectType('App\Models\ModeratedProfile::class')
- ->user(request()->user())
- ->action('admin.moderated-profiles.create')
- ->metadata([
- 'profile_existed' => false,
- ])
- ->accessLevel('admin')
- ->save();
- return $rec;
- }
- abort(400, 'Invalid account');
- }
- }
|