DeleteAccountPipeline.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. namespace App\Jobs\DeletePipeline;
  3. use Illuminate\Bus\Queueable;
  4. use Illuminate\Queue\SerializesModels;
  5. use Illuminate\Queue\InteractsWithQueue;
  6. use Illuminate\Contracts\Queue\ShouldQueue;
  7. use Illuminate\Foundation\Bus\Dispatchable;
  8. use DB;
  9. use Storage;
  10. use Illuminate\Support\Str;
  11. use App\Services\AccountService;
  12. use App\Services\PublicTimelineService;
  13. use App\{
  14. AccountInterstitial,
  15. AccountLog,
  16. Avatar,
  17. Bookmark,
  18. Collection,
  19. CollectionItem,
  20. Contact,
  21. DirectMessage,
  22. EmailVerification,
  23. Follower,
  24. FollowRequest,
  25. Hashtag,
  26. HashtagFollow,
  27. ImportData,
  28. ImportJob,
  29. Like,
  30. Media,
  31. MediaTag,
  32. Mention,
  33. Notification,
  34. OauthClient,
  35. Profile,
  36. ProfileSponsor,
  37. Report,
  38. ReportComment,
  39. ReportLog,
  40. StatusHashtag,
  41. StatusArchived,
  42. Status,
  43. Story,
  44. StoryView,
  45. User,
  46. UserDevice,
  47. UserFilter,
  48. UserSetting,
  49. };
  50. use App\Models\UserPronoun;
  51. class DeleteAccountPipeline implements ShouldQueue
  52. {
  53. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  54. protected $user;
  55. public $timeout = 900;
  56. public function __construct(User $user)
  57. {
  58. $this->user = $user;
  59. }
  60. public function handle()
  61. {
  62. $user = $this->user;
  63. $this->deleteUserColumns($user);
  64. AccountService::del($user->profile_id);
  65. DB::transaction(function() use ($user) {
  66. AccountLog::whereItemType('App\User')->whereItemId($user->id)->forceDelete();
  67. });
  68. DB::transaction(function() use ($user) {
  69. AccountInterstitial::whereUserId($user->id)->delete();
  70. });
  71. DB::transaction(function() use ($user) {
  72. if($user->profile) {
  73. $avatar = $user->profile->avatar;
  74. $path = $avatar->media_path;
  75. if(!in_array($path, [
  76. 'public/avatars/default.jpg',
  77. 'public/avatars/default.png'
  78. ])) {
  79. if(config('pixelfed.cloud_storage')) {
  80. $disk = Storage::disk(config('filesystems.cloud'));
  81. if($disk->exists($path)) {
  82. $disk->delete($path);
  83. }
  84. }
  85. $disk = Storage::disk(config('filesystems.local'));
  86. if($disk->exists($path)) {
  87. $disk->delete($path);
  88. }
  89. }
  90. $avatar->forceDelete();
  91. }
  92. $id = $user->profile_id;
  93. ImportData::whereProfileId($id)
  94. ->cursor()
  95. ->each(function($data) {
  96. $path = storage_path('app/'.$data->path);
  97. if(is_file($path)) {
  98. unlink($path);
  99. }
  100. $data->delete();
  101. });
  102. ImportJob::whereProfileId($id)
  103. ->cursor()
  104. ->each(function($data) {
  105. $path = storage_path('app/'.$data->media_json);
  106. if(is_file($path)) {
  107. unlink($path);
  108. }
  109. $data->delete();
  110. });
  111. MediaTag::whereProfileId($id)->delete();
  112. Bookmark::whereProfileId($id)->forceDelete();
  113. EmailVerification::whereUserId($user->id)->forceDelete();
  114. StatusHashtag::whereProfileId($id)->delete();
  115. DirectMessage::whereFromId($id)->orWhere('to_id', $id)->delete();
  116. StatusArchived::whereProfileId($id)->delete();
  117. UserPronoun::whereProfileId($id)->delete();
  118. FollowRequest::whereFollowingId($id)
  119. ->orWhere('follower_id', $id)
  120. ->forceDelete();
  121. Follower::whereProfileId($id)
  122. ->orWhere('following_id', $id)
  123. ->forceDelete();
  124. Like::whereProfileId($id)->forceDelete();
  125. });
  126. DB::transaction(function() use ($user) {
  127. $pid = $this->user->profile_id;
  128. StoryView::whereProfileId($pid)->delete();
  129. $stories = Story::whereProfileId($pid)->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. });
  138. DB::transaction(function() use ($user) {
  139. $medias = Media::whereUserId($user->id)->get();
  140. foreach($medias as $media) {
  141. if(config('pixelfed.cloud_storage')) {
  142. $disk = Storage::disk(config('filesystems.cloud'));
  143. if($disk->exists($media->media_path)) {
  144. $disk->delete($media->media_path);
  145. }
  146. if($disk->exists($media->thumbnail_path)) {
  147. $disk->delete($media->thumbnail_path);
  148. }
  149. }
  150. $disk = Storage::disk(config('filesystems.local'));
  151. if($disk->exists($media->media_path)) {
  152. $disk->delete($media->media_path);
  153. }
  154. if($disk->exists($media->thumbnail_path)) {
  155. $disk->delete($media->thumbnail_path);
  156. }
  157. $media->forceDelete();
  158. }
  159. });
  160. DB::transaction(function() use ($user) {
  161. Mention::whereProfileId($user->profile_id)->forceDelete();
  162. Notification::whereProfileId($user->profile_id)
  163. ->orWhere('actor_id', $user->profile_id)
  164. ->forceDelete();
  165. });
  166. DB::transaction(function() use ($user) {
  167. $collections = Collection::whereProfileId($user->profile_id)->get();
  168. foreach ($collections as $collection) {
  169. $collection->items()->delete();
  170. $collection->delete();
  171. }
  172. Contact::whereUserId($user->id)->delete();
  173. HashtagFollow::whereUserId($user->id)->delete();
  174. OauthClient::whereUserId($user->id)->delete();
  175. DB::table('oauth_access_tokens')->whereUserId($user->id)->delete();
  176. DB::table('oauth_auth_codes')->whereUserId($user->id)->delete();
  177. ProfileSponsor::whereProfileId($user->profile_id)->delete();
  178. });
  179. DB::transaction(function() use ($user) {
  180. Status::whereProfileId($user->profile_id)->forceDelete();
  181. Report::whereUserId($user->id)->forceDelete();
  182. PublicTimelineService::warmCache(true, 400);
  183. $this->deleteProfile($user);
  184. });
  185. }
  186. protected function deleteProfile($user) {
  187. DB::transaction(function() use ($user) {
  188. Profile::whereUserId($user->id)->delete();
  189. $this->deleteUserSettings($user);
  190. });
  191. }
  192. protected function deleteUserSettings($user) {
  193. DB::transaction(function() use ($user) {
  194. UserDevice::whereUserId($user->id)->forceDelete();
  195. UserFilter::whereUserId($user->id)->forceDelete();
  196. UserSetting::whereUserId($user->id)->forceDelete();
  197. });
  198. }
  199. protected function deleteUserColumns($user)
  200. {
  201. DB::transaction(function() use ($user) {
  202. $user->status = 'deleted';
  203. $user->name = 'deleted';
  204. $user->email = $user->id;
  205. $user->password = '';
  206. $user->remember_token = null;
  207. $user->is_admin = false;
  208. $user->{'2fa_enabled'} = false;
  209. $user->{'2fa_secret'} = null;
  210. $user->{'2fa_backup_codes'} = null;
  211. $user->{'2fa_setup_at'} = null;
  212. $user->save();
  213. });
  214. }
  215. }