1
0

PixelfedDirectoryController.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Models\ConfigCache;
  4. use App\Services\AccountService;
  5. use App\Services\StatusService;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Support\Str;
  8. use Cache;
  9. use Storage;
  10. use App\Status;
  11. use App\User;
  12. class PixelfedDirectoryController extends Controller
  13. {
  14. public function get(Request $request)
  15. {
  16. if (! $request->filled('sk')) {
  17. abort(404);
  18. }
  19. if (! config_cache('pixelfed.directory.submission-key')) {
  20. abort(404);
  21. }
  22. if (! hash_equals(config_cache('pixelfed.directory.submission-key'), $request->input('sk'))) {
  23. abort(403);
  24. }
  25. $res = $this->buildListing();
  26. return response()->json($res, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  27. }
  28. public function buildListing()
  29. {
  30. $res = config_cache('pixelfed.directory');
  31. if ($res) {
  32. $res = is_string($res) ? json_decode($res, true) : $res;
  33. }
  34. $res['_domain'] = config_cache('pixelfed.domain.app');
  35. $res['_sk'] = config_cache('pixelfed.directory.submission-key');
  36. $res['_ts'] = config_cache('pixelfed.directory.submission-ts');
  37. $res['version'] = config_cache('pixelfed.version');
  38. if (empty($res['summary'])) {
  39. $summary = ConfigCache::whereK('app.short_description')->pluck('v');
  40. $res['summary'] = $summary ? $summary[0] : null;
  41. }
  42. if (isset($res['admin'])) {
  43. $res['admin'] = AccountService::get($res['admin'], true);
  44. }
  45. if (isset($res['banner_image']) && ! empty($res['banner_image'])) {
  46. $res['banner_image'] = url(Storage::url($res['banner_image']));
  47. }
  48. if (isset($res['favourite_posts'])) {
  49. $res['favourite_posts'] = collect($res['favourite_posts'])->map(function ($id) {
  50. return StatusService::get($id);
  51. })
  52. ->filter(function ($post) {
  53. return $post && isset($post['account']);
  54. })
  55. ->map(function ($post) {
  56. return [
  57. 'avatar' => $post['account']['avatar'],
  58. 'display_name' => $post['account']['display_name'],
  59. 'username' => $post['account']['username'],
  60. 'media' => $post['media_attachments'][0]['url'],
  61. 'url' => $post['url'],
  62. ];
  63. })
  64. ->values();
  65. }
  66. $guidelines = ConfigCache::whereK('app.rules')->first();
  67. if ($guidelines) {
  68. $res['community_guidelines'] = json_decode($guidelines->v, true);
  69. }
  70. $openRegistration = (bool) config_cache('pixelfed.open_registration');
  71. $res['open_registration'] = $openRegistration;
  72. $curatedOnboarding = (bool) config_cache('instance.curated_registration.enabled');
  73. $res['curated_onboarding'] = $curatedOnboarding;
  74. $oauthEnabled = ConfigCache::whereK('pixelfed.oauth_enabled')->first();
  75. if ($oauthEnabled) {
  76. $keys = file_exists(storage_path('oauth-public.key')) && file_exists(storage_path('oauth-private.key'));
  77. $res['oauth_enabled'] = (bool) $oauthEnabled && $keys;
  78. }
  79. $activityPubEnabled = ConfigCache::whereK('federation.activitypub.enabled')->first();
  80. if ($activityPubEnabled) {
  81. $res['activitypub_enabled'] = (bool) $activityPubEnabled;
  82. }
  83. $res['feature_config'] = [
  84. 'media_types' => Str::of(config_cache('pixelfed.media_types'))->explode(','),
  85. 'image_quality' => config_cache('pixelfed.image_quality'),
  86. 'optimize_image' => (bool) config_cache('pixelfed.optimize_image'),
  87. 'max_photo_size' => config_cache('pixelfed.max_photo_size'),
  88. 'max_caption_length' => config_cache('pixelfed.max_caption_length'),
  89. 'max_altext_length' => config_cache('pixelfed.max_altext_length'),
  90. 'enforce_account_limit' => (bool) config_cache('pixelfed.enforce_account_limit'),
  91. 'max_account_size' => config_cache('pixelfed.max_account_size'),
  92. 'max_album_length' => config_cache('pixelfed.max_album_length'),
  93. 'account_deletion' => (bool) config_cache('pixelfed.account_deletion'),
  94. ];
  95. $res['is_eligible'] = $this->validVal($res, 'admin') &&
  96. $this->validVal($res, 'summary', null, 10) &&
  97. $this->validVal($res, 'favourite_posts', 3) &&
  98. $this->validVal($res, 'contact_email') &&
  99. $this->validVal($res, 'privacy_pledge') &&
  100. $this->validVal($res, 'location');
  101. if (config_cache('pixelfed.directory.testimonials')) {
  102. $res['testimonials'] = collect(json_decode(config_cache('pixelfed.directory.testimonials'), true))
  103. ->map(function ($testimonial) {
  104. $profile = AccountService::get($testimonial['profile_id']);
  105. return [
  106. 'profile' => [
  107. 'username' => $profile['username'],
  108. 'display_name' => $profile['display_name'],
  109. 'avatar' => $profile['avatar'],
  110. 'created_at' => $profile['created_at'],
  111. ],
  112. 'body' => $testimonial['body'],
  113. ];
  114. });
  115. }
  116. $res['features_enabled'] = [
  117. 'stories' => (bool) config_cache('instance.stories.enabled'),
  118. ];
  119. $statusesCount = Cache::remember('api:nodeinfo:statuses', 21600, function() {
  120. return Status::whereLocal(true)->count();
  121. });
  122. $usersCount = Cache::remember('api:nodeinfo:users', 43200, function() {
  123. return User::count();
  124. });
  125. $res['stats'] = [
  126. 'user_count' => (int) $usersCount,
  127. 'post_count' => (int) $statusesCount,
  128. ];
  129. $res['primary_locale'] = config('app.locale');
  130. $hash = hash('sha256', json_encode($res));
  131. $res['_hash'] = $hash;
  132. ksort($res);
  133. return $res;
  134. }
  135. protected function validVal($res, $val, $count = false, $minLen = false)
  136. {
  137. if (! isset($res[$val])) {
  138. return false;
  139. }
  140. if ($count) {
  141. return count($res[$val]) >= $count;
  142. }
  143. if ($minLen) {
  144. return strlen($res[$val]) >= $minLen;
  145. }
  146. return $res[$val];
  147. }
  148. }