DeleteAccountPipeline.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <?php
  2. namespace App\Jobs\DeletePipeline;
  3. use App\AccountInterstitial;
  4. use App\AccountLog;
  5. use App\Bookmark;
  6. use App\Collection;
  7. use App\Contact;
  8. use App\DirectMessage;
  9. use App\EmailVerification;
  10. use App\Follower;
  11. use App\FollowRequest;
  12. use App\HashtagFollow;
  13. use App\Jobs\StatusPipeline\StatusDelete;
  14. use App\Like;
  15. use App\MediaTag;
  16. use App\Mention;
  17. use App\Models\Conversation;
  18. use App\Models\CustomFilter;
  19. use App\Models\ImportPost;
  20. use App\Models\Poll;
  21. use App\Models\PollVote;
  22. use App\Models\Portfolio;
  23. use App\Models\ProfileAlias;
  24. use App\Models\ProfileMigration;
  25. use App\Models\RemoteAuth;
  26. use App\Models\RemoteReport;
  27. use App\Models\UserPronoun;
  28. use App\Notification;
  29. use App\OauthClient;
  30. use App\Profile;
  31. use App\ProfileSponsor;
  32. use App\Report;
  33. use App\Services\AccountService;
  34. use App\Services\FollowerService;
  35. use App\Services\PublicTimelineService;
  36. use App\Status;
  37. use App\StatusArchived;
  38. use App\StatusHashtag;
  39. use App\StatusView;
  40. use App\Story;
  41. use App\StoryView;
  42. use App\User;
  43. use App\UserDevice;
  44. use App\UserFilter;
  45. use App\UserSetting;
  46. use DB;
  47. use Illuminate\Bus\Queueable;
  48. use Illuminate\Contracts\Queue\ShouldQueue;
  49. use Illuminate\Foundation\Bus\Dispatchable;
  50. use Illuminate\Queue\InteractsWithQueue;
  51. use Illuminate\Queue\SerializesModels;
  52. use Storage;
  53. class DeleteAccountPipeline implements ShouldQueue
  54. {
  55. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  56. protected $user;
  57. public $timeout = 1800;
  58. public $tries = 3;
  59. public $maxExceptions = 1;
  60. public $deleteWhenMissingModels = true;
  61. public function __construct(User $user)
  62. {
  63. $this->user = $user;
  64. }
  65. public function handle()
  66. {
  67. $user = $this->user;
  68. $profile = $user->profile;
  69. $id = $user->profile_id;
  70. $cloudStorageEnabled = (bool) config_cache('pixelfed.cloud_storage');
  71. $cloudDisk = config('filesystems.cloud');
  72. if ($user && $user->id && is_numeric($user->id)) {
  73. $directory = 'imports/'.$user->id;
  74. if (Storage::exists($directory)) {
  75. Storage::deleteDirectory($directory);
  76. }
  77. }
  78. if ($id && is_numeric($id)) {
  79. $mediaDir = 'public/m/_v2/'.$id;
  80. if (Storage::exists($mediaDir)) {
  81. Storage::deleteDirectory($mediaDir);
  82. }
  83. if ($cloudStorageEnabled && $cloudDisk) {
  84. if (Storage::disk($cloudDisk)->exists($mediaDir)) {
  85. Storage::disk($cloudDisk)->deleteDirectory($mediaDir);
  86. }
  87. }
  88. }
  89. Status::whereProfileId($id)->chunk(50, function ($statuses) {
  90. foreach ($statuses as $status) {
  91. StatusDelete::dispatch($status);
  92. }
  93. });
  94. DB::table('user_oidc_mappings')->whereUserId($user->id)->delete();
  95. CustomFilter::whereProfileId($id)->delete();
  96. StatusView::whereProfileId($id)->delete();
  97. ProfileAlias::whereProfileId($id)->delete();
  98. ProfileMigration::whereProfileId($id)->delete();
  99. RemoteReport::whereAccountId($id)->delete();
  100. RemoteAuth::whereUserId($user->id)->delete();
  101. AccountLog::whereItemType('App\User')->whereItemId($user->id)->forceDelete();
  102. AccountInterstitial::whereUserId($user->id)->delete();
  103. $profile->avatar->forceDelete();
  104. PollVote::whereProfileId($id)->delete();
  105. Poll::whereProfileId($id)->delete();
  106. Portfolio::whereProfileId($id)->delete();
  107. ImportPost::whereProfileId($id)->delete();
  108. MediaTag::whereProfileId($id)->delete();
  109. Bookmark::whereProfileId($id)->forceDelete();
  110. EmailVerification::whereUserId($user->id)->forceDelete();
  111. StatusHashtag::whereProfileId($id)->delete();
  112. DirectMessage::whereFromId($id)->orWhere('to_id', $id)->delete();
  113. Conversation::whereFromId($id)->orWhere('to_id', $id)->delete();
  114. StatusArchived::whereProfileId($id)->delete();
  115. UserPronoun::whereProfileId($id)->delete();
  116. FollowRequest::whereFollowingId($id)
  117. ->orWhere('follower_id', $id)
  118. ->forceDelete();
  119. Follower::whereProfileId($id)
  120. ->orWhere('following_id', $id)
  121. ->each(function ($follow) {
  122. FollowerService::remove($follow->profile_id, $follow->following_id);
  123. $follow->delete();
  124. });
  125. FollowerService::delCache($id);
  126. Like::whereProfileId($id)->forceDelete();
  127. Mention::whereProfileId($id)->forceDelete();
  128. StoryView::whereProfileId($id)->delete();
  129. $stories = Story::whereProfileId($id)->get();
  130. foreach ($stories as $story) {
  131. $path = storage_path('app/'.$story->path);
  132. if (is_file($path)) {
  133. unlink($path);
  134. }
  135. $story->forceDelete();
  136. }
  137. UserDevice::whereUserId($user->id)->forceDelete();
  138. UserFilter::whereUserId($user->id)->forceDelete();
  139. UserSetting::whereUserId($user->id)->forceDelete();
  140. Mention::whereProfileId($id)->forceDelete();
  141. Notification::whereProfileId($id)
  142. ->orWhere('actor_id', $id)
  143. ->forceDelete();
  144. $collections = Collection::whereProfileId($id)->get();
  145. foreach ($collections as $collection) {
  146. $collection->items()->delete();
  147. $collection->delete();
  148. }
  149. Contact::whereUserId($user->id)->delete();
  150. HashtagFollow::whereUserId($user->id)->delete();
  151. OauthClient::whereUserId($user->id)->delete();
  152. DB::table('oauth_access_tokens')->whereUserId($user->id)->delete();
  153. DB::table('oauth_auth_codes')->whereUserId($user->id)->delete();
  154. ProfileSponsor::whereProfileId($id)->delete();
  155. Report::whereUserId($user->id)->forceDelete();
  156. PublicTimelineService::warmCache(true, 400);
  157. $this->deleteUserColumns($user);
  158. AccountService::del($user->profile_id);
  159. Profile::whereUserId($user->id)->delete();
  160. }
  161. protected function deleteUserColumns($user)
  162. {
  163. DB::transaction(function () use ($user) {
  164. $user->status = 'deleted';
  165. $user->name = 'deleted';
  166. $user->email = $user->id;
  167. $user->password = '';
  168. $user->remember_token = null;
  169. $user->is_admin = false;
  170. $user->expo_token = null;
  171. $user->{'2fa_enabled'} = false;
  172. $user->{'2fa_secret'} = null;
  173. $user->{'2fa_backup_codes'} = null;
  174. $user->{'2fa_setup_at'} = null;
  175. $user->save();
  176. });
  177. }
  178. }