Merge pull request #4215 from pixelfed/staging

Staging
pull/4217/head
daniel 2 years ago committed by GitHub
commit 67d89e599d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -17,16 +17,20 @@ use App\{
EmailVerification,
Follower,
FollowRequest,
Media,
Notification,
Profile,
User,
UserFilter
UserDevice,
UserFilter,
UserSetting
};
use League\Fractal;
use League\Fractal\Serializer\ArraySerializer;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use App\Transformer\Api\Mastodon\v1\AccountTransformer;
use App\Services\AccountService;
use App\Services\NotificationService;
use App\Services\UserFilterService;
use App\Services\RelationshipService;
use App\Jobs\FollowPipeline\FollowAcceptPipeline;
@ -39,7 +43,8 @@ class AccountController extends Controller
'user.block',
];
const FILTER_LIMIT = 'You cannot block or mute more than 100 accounts';
const FILTER_LIMIT_MUTE_TEXT = 'You cannot mute more than ';
const FILTER_LIMIT_BLOCK_TEXT = 'You cannot block more than ';
public function __construct()
{
@ -145,16 +150,17 @@ class AccountController extends Controller
public function mute(Request $request)
{
$this->validate($request, [
'type' => 'required|alpha_dash',
'type' => 'required|string|in:user',
'item' => 'required|integer|min:1',
]);
$user = Auth::user()->profile;
$count = UserFilterService::muteCount($user->id);
abort_if($count >= 100, 422, self::FILTER_LIMIT);
$pid = $request->user()->profile_id;
$count = UserFilterService::muteCount($pid);
$maxLimit = intval(config('instance.user_filters.max_user_mutes'));
abort_if($count >= $maxLimit, 422, self::FILTER_LIMIT_MUTE_TEXT . $maxLimit . ' accounts');
if($count == 0) {
$filterCount = UserFilter::whereUserId($user->id)->count();
abort_if($filterCount >= 100, 422, self::FILTER_LIMIT);
$filterCount = UserFilter::whereUserId($pid)->count();
abort_if($filterCount >= $maxLimit, 422, self::FILTER_LIMIT_MUTE_TEXT . $maxLimit . ' accounts');
}
$type = $request->input('type');
$item = $request->input('item');
@ -167,7 +173,7 @@ class AccountController extends Controller
switch ($type) {
case 'user':
$profile = Profile::findOrFail($item);
if ($profile->id == $user->id) {
if ($profile->id == $pid) {
return abort(403);
}
$class = get_class($profile);
@ -177,29 +183,30 @@ class AccountController extends Controller
}
$filter = UserFilter::firstOrCreate([
'user_id' => $user->id,
'user_id' => $pid,
'filterable_id' => $filterable['id'],
'filterable_type' => $filterable['type'],
'filter_type' => 'mute',
]);
$pid = $user->id;
Cache::forget("user:filter:list:$pid");
Cache::forget("feature:discover:posts:$pid");
Cache::forget("api:local:exp:rec:$pid");
RelationshipService::refresh($pid, $profile->id);
UserFilterService::mute($pid, $filterable['id']);
$res = RelationshipService::refresh($pid, $profile->id);
return redirect()->back();
if($request->wantsJson()) {
return response()->json($res);
} else {
return redirect()->back();
}
}
public function unmute(Request $request)
{
$this->validate($request, [
'type' => 'required|alpha_dash',
'type' => 'required|string|in:user',
'item' => 'required|integer|min:1',
]);
$user = Auth::user()->profile;
$pid = $request->user()->profile_id;
$type = $request->input('type');
$item = $request->input('item');
$action = $type . '.mute';
@ -211,7 +218,7 @@ class AccountController extends Controller
switch ($type) {
case 'user':
$profile = Profile::findOrFail($item);
if ($profile->id == $user->id) {
if ($profile->id == $pid) {
return abort(403);
}
$class = get_class($profile);
@ -224,24 +231,21 @@ class AccountController extends Controller
break;
}
$filter = UserFilter::whereUserId($user->id)
$filter = UserFilter::whereUserId($pid)
->whereFilterableId($filterable['id'])
->whereFilterableType($filterable['type'])
->whereFilterType('mute')
->first();
if($filter) {
UserFilterService::unmute($pid, $filterable['id']);
$filter->delete();
}
$pid = $user->id;
Cache::forget("user:filter:list:$pid");
Cache::forget("feature:discover:posts:$pid");
Cache::forget("api:local:exp:rec:$pid");
RelationshipService::refresh($pid, $profile->id);
$res = RelationshipService::refresh($pid, $profile->id);
if($request->wantsJson()) {
return response()->json([200]);
return response()->json($res);
} else {
return redirect()->back();
}
@ -250,16 +254,16 @@ class AccountController extends Controller
public function block(Request $request)
{
$this->validate($request, [
'type' => 'required|alpha_dash',
'type' => 'required|string|in:user',
'item' => 'required|integer|min:1',
]);
$user = Auth::user()->profile;
$count = UserFilterService::blockCount($user->id);
abort_if($count >= 100, 422, self::FILTER_LIMIT);
$pid = $request->user()->profile_id;
$count = UserFilterService::blockCount($pid);
$maxLimit = intval(config('instance.user_filters.max_user_blocks'));
abort_if($count >= $maxLimit, 422, self::FILTER_LIMIT_BLOCK_TEXT . $maxLimit . ' accounts');
if($count == 0) {
$filterCount = UserFilter::whereUserId($user->id)->count();
abort_if($filterCount >= 100, 422, self::FILTER_LIMIT);
$filterCount = UserFilter::whereUserId($pid)->whereFilterType('block')->count();
abort_if($filterCount >= $maxLimit, 422, self::FILTER_LIMIT_BLOCK_TEXT . $maxLimit . ' accounts');
}
$type = $request->input('type');
$item = $request->input('item');
@ -271,41 +275,49 @@ class AccountController extends Controller
switch ($type) {
case 'user':
$profile = Profile::findOrFail($item);
if ($profile->id == $user->id || ($profile->user && $profile->user->is_admin == true)) {
if ($profile->id == $pid || ($profile->user && $profile->user->is_admin == true)) {
return abort(403);
}
$class = get_class($profile);
$filterable['id'] = $profile->id;
$filterable['type'] = $class;
Follower::whereProfileId($profile->id)->whereFollowingId($user->id)->delete();
Notification::whereProfileId($user->id)->whereActorId($profile->id)->delete();
Follower::whereProfileId($profile->id)->whereFollowingId($pid)->delete();
Notification::whereProfileId($pid)
->whereActorId($profile->id)
->get()
->map(function($n) use($pid) {
NotificationService::del($pid, $n['id']);
$n->forceDelete();
});
break;
}
$filter = UserFilter::firstOrCreate([
'user_id' => $user->id,
'user_id' => $pid,
'filterable_id' => $filterable['id'],
'filterable_type' => $filterable['type'],
'filter_type' => 'block',
]);
$pid = $user->id;
Cache::forget("user:filter:list:$pid");
Cache::forget("api:local:exp:rec:$pid");
RelationshipService::refresh($pid, $profile->id);
UserFilterService::block($pid, $filterable['id']);
$res = RelationshipService::refresh($pid, $profile->id);
return redirect()->back();
if($request->wantsJson()) {
return response()->json($res);
} else {
return redirect()->back();
}
}
public function unblock(Request $request)
{
$this->validate($request, [
'type' => 'required|alpha_dash',
'type' => 'required|string|in:user',
'item' => 'required|integer|min:1',
]);
$user = Auth::user()->profile;
$pid = $request->user()->profile_id;
$type = $request->input('type');
$item = $request->input('item');
$action = $type . '.block';
@ -316,7 +328,7 @@ class AccountController extends Controller
switch ($type) {
case 'user':
$profile = Profile::findOrFail($item);
if ($profile->id == $user->id) {
if ($profile->id == $pid) {
return abort(403);
}
$class = get_class($profile);
@ -330,23 +342,24 @@ class AccountController extends Controller
}
$filter = UserFilter::whereUserId($user->id)
$filter = UserFilter::whereUserId($pid)
->whereFilterableId($filterable['id'])
->whereFilterableType($filterable['type'])
->whereFilterType('block')
->first();
if($filter) {
UserFilterService::unblock($pid, $filterable['id']);
$filter->delete();
}
$pid = $user->id;
Cache::forget("user:filter:list:$pid");
Cache::forget("feature:discover:posts:$pid");
Cache::forget("api:local:exp:rec:$pid");
RelationshipService::refresh($pid, $profile->id);
$res = RelationshipService::refresh($pid, $profile->id);
return redirect()->back();
if($request->wantsJson()) {
return response()->json($res);
} else {
return redirect()->back();
}
}
public function followRequests(Request $request)
@ -513,25 +526,25 @@ class AccountController extends Controller
}
}
protected function twoFactorBackupCheck($request, $code, User $user)
{
$backupCodes = $user->{'2fa_backup_codes'};
if($backupCodes) {
$codes = json_decode($backupCodes, true);
foreach ($codes as $c) {
if(hash_equals($c, $code)) {
$codes = array_flatten(array_diff($codes, [$code]));
$user->{'2fa_backup_codes'} = json_encode($codes);
$user->save();
$request->session()->push('2fa.session.active', true);
return true;
}
}
return false;
} else {
protected function twoFactorBackupCheck($request, $code, User $user)
{
$backupCodes = $user->{'2fa_backup_codes'};
if($backupCodes) {
$codes = json_decode($backupCodes, true);
foreach ($codes as $c) {
if(hash_equals($c, $code)) {
$codes = array_flatten(array_diff($codes, [$code]));
$user->{'2fa_backup_codes'} = json_encode($codes);
$user->save();
$request->session()->push('2fa.session.active', true);
return true;
}
}
return false;
}
}
} else {
return false;
}
}
public function accountRestored(Request $request)
{

@ -43,6 +43,7 @@ use App\Transformer\Api\{
use App\Http\Controllers\FollowerController;
use League\Fractal\Serializer\ArraySerializer;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use App\Http\Controllers\AccountController;
use App\Http\Controllers\StatusController;
use App\Jobs\AvatarPipeline\AvatarOptimize;
@ -939,6 +940,25 @@ class ApiV1Controller extends Controller
abort(400, 'You cannot block an admin');
}
$count = UserFilterService::blockCount($pid);
$maxLimit = intval(config('instance.user_filters.max_user_blocks'));
if($count == 0) {
$filterCount = UserFilter::whereUserId($pid)
->whereFilterType('block')
->get()
->map(function($rec) {
return AccountService::get($rec->filterable_id, true);
})
->filter(function($account) {
return $account && isset($account['id']);
})
->values()
->count();
abort_if($filterCount >= $maxLimit, 422, AccountController::FILTER_LIMIT_BLOCK_TEXT . $maxLimit . ' accounts');
} else {
abort_if($count >= $maxLimit, 422, AccountController::FILTER_LIMIT_BLOCK_TEXT . $maxLimit . ' accounts');
}
Follower::whereProfileId($profile->id)->whereFollowingId($pid)->delete();
Follower::whereProfileId($pid)->whereFollowingId($profile->id)->delete();
Notification::whereProfileId($pid)->whereActorId($profile->id)->delete();
@ -950,8 +970,6 @@ class ApiV1Controller extends Controller
'filter_type' => 'block',
]);
Cache::forget("user:filter:list:$pid");
Cache::forget("api:local:exp:rec:$pid");
RelationshipService::refresh($pid, $id);
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
@ -980,15 +998,17 @@ class ApiV1Controller extends Controller
$profile = Profile::findOrFail($id);
UserFilter::whereUserId($pid)
$filter = UserFilter::whereUserId($pid)
->whereFilterableId($profile->id)
->whereFilterableType('App\Profile')
->whereFilterType('block')
->delete();
->first();
Cache::forget("user:filter:list:$pid");
Cache::forget("api:local:exp:rec:$pid");
RelationshipService::refresh($pid, $id);
if($filter) {
$filter->delete();
UserFilterService::unblock($pid, $profile->id);
RelationshipService::refresh($pid, $id);
}
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
$res = $this->fractal->createData($resource)->toArray();
@ -1823,6 +1843,25 @@ class ApiV1Controller extends Controller
$account = Profile::findOrFail($id);
$count = UserFilterService::muteCount($pid);
$maxLimit = intval(config('instance.user_filters.max_user_mutes'));
if($count == 0) {
$filterCount = UserFilter::whereUserId($pid)
->whereFilterType('mute')
->get()
->map(function($rec) {
return AccountService::get($rec->filterable_id, true);
})
->filter(function($account) {
return $account && isset($account['id']);
})
->values()
->count();
abort_if($filterCount >= $maxLimit, 422, AccountController::FILTER_LIMIT_MUTE_TEXT . $maxLimit . ' accounts');
} else {
abort_if($count >= $maxLimit, 422, AccountController::FILTER_LIMIT_MUTE_TEXT . $maxLimit . ' accounts');
}
$filter = UserFilter::firstOrCreate([
'user_id' => $pid,
'filterable_id' => $account->id,
@ -1830,9 +1869,6 @@ class ApiV1Controller extends Controller
'filter_type' => 'mute',
]);
Cache::forget("user:filter:list:$pid");
Cache::forget("feature:discover:posts:$pid");
Cache::forget("api:local:exp:rec:$pid");
RelationshipService::refresh($pid, $id);
$resource = new Fractal\Resource\Item($account, new RelationshipTransformer());
@ -1858,23 +1894,21 @@ class ApiV1Controller extends Controller
return $this->json(['error' => 'You cannot unmute yourself'], 500);
}
$account = Profile::findOrFail($id);
$profile = Profile::findOrFail($id);
$filter = UserFilter::whereUserId($pid)
->whereFilterableId($account->id)
->whereFilterableId($profile->id)
->whereFilterableType('App\Profile')
->whereFilterType('mute')
->first();
if($filter) {
$filter->delete();
Cache::forget("user:filter:list:$pid");
Cache::forget("feature:discover:posts:$pid");
Cache::forget("api:local:exp:rec:$pid");
UserFilterService::unmute($pid, $profile->id);
RelationshipService::refresh($pid, $id);
}
$resource = new Fractal\Resource\Item($account, new RelationshipTransformer());
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
$res = $this->fractal->createData($resource)->toArray();
return $this->json($res);
}

@ -148,6 +148,7 @@ class StatusService
Cache::forget('status:thumb:nsfw1' . $id);
Cache::forget('pf:services:sh:id:' . $id);
PublicTimelineService::rem($id);
NetworkTimelineService::rem($id);
}
Cache::forget(self::key($id, false));

@ -14,7 +14,7 @@ class UserFilterService
public static function mutes(int $profile_id)
{
$key = self::USER_MUTES_KEY . $profile_id;
$warm = Cache::has($key . ':cached');
$warm = Cache::has($key . ':cached-v0');
if($warm) {
return Redis::zrevrange($key, 0, -1) ?? [];
} else {
@ -24,11 +24,22 @@ class UserFilterService
$ids = UserFilter::whereFilterType('mute')
->whereUserId($profile_id)
->pluck('filterable_id')
->map(function($id) {
$acct = AccountService::get($id, true);
if(!$acct) {
return false;
}
return $acct['id'];
})
->filter(function($res) {
return $res;
})
->values()
->toArray();
foreach ($ids as $muted_id) {
Redis::zadd($key, (int) $muted_id, (int) $muted_id);
}
Cache::set($key . ':cached', 1, 7776000);
Cache::set($key . ':cached-v0', 1, 7776000);
return $ids;
}
}
@ -36,7 +47,7 @@ class UserFilterService
public static function blocks(int $profile_id)
{
$key = self::USER_BLOCKS_KEY . $profile_id;
$warm = Cache::has($key . ':cached');
$warm = Cache::has($key . ':cached-v0');
if($warm) {
return Redis::zrevrange($key, 0, -1) ?? [];
} else {
@ -46,11 +57,22 @@ class UserFilterService
$ids = UserFilter::whereFilterType('block')
->whereUserId($profile_id)
->pluck('filterable_id')
->map(function($id) {
$acct = AccountService::get($id, true);
if(!$acct) {
return false;
}
return $acct['id'];
})
->filter(function($res) {
return $res;
})
->values()
->toArray();
foreach ($ids as $blocked_id) {
Redis::zadd($key, (int) $blocked_id, (int) $blocked_id);
}
Cache::set($key . ':cached', 1, 7776000);
Cache::set($key . ':cached-v0', 1, 7776000);
return $ids;
}
}
@ -62,6 +84,9 @@ class UserFilterService
public static function mute(int $profile_id, int $muted_id)
{
if($profile_id == $muted_id) {
return false;
}
$key = self::USER_MUTES_KEY . $profile_id;
$mutes = self::mutes($profile_id);
$exists = in_array($muted_id, $mutes);
@ -73,6 +98,9 @@ class UserFilterService
public static function unmute(int $profile_id, string $muted_id)
{
if($profile_id == $muted_id) {
return false;
}
$key = self::USER_MUTES_KEY . $profile_id;
$mutes = self::mutes($profile_id);
$exists = in_array($muted_id, $mutes);
@ -84,6 +112,9 @@ class UserFilterService
public static function block(int $profile_id, int $blocked_id)
{
if($profile_id == $blocked_id) {
return false;
}
$key = self::USER_BLOCKS_KEY . $profile_id;
$exists = in_array($blocked_id, self::blocks($profile_id));
if(!$exists) {
@ -94,6 +125,9 @@ class UserFilterService
public static function unblock(int $profile_id, string $blocked_id)
{
if($profile_id == $blocked_id) {
return false;
}
$key = self::USER_BLOCKS_KEY . $profile_id;
$exists = in_array($blocked_id, self::blocks($profile_id));
if($exists) {

447
composer.lock generated

File diff suppressed because it is too large Load Diff

@ -107,4 +107,9 @@ return [
'admin_invites' => [
'enabled' => env('PF_ADMIN_INVITES_ENABLED', true)
],
'user_filters' => [
'max_user_blocks' => env('PF_MAX_USER_BLOCKS', 50),
'max_user_mutes' => env('PF_MAX_USER_MUTES', 50)
]
];

570
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1 +1 @@
(()=>{"use strict";var e,r,t,n={},o={};function a(e){var r=o[e];if(void 0!==r)return r.exports;var t=o[e]={id:e,loaded:!1,exports:{}};return n[e].call(t.exports,t,t.exports,a),t.loaded=!0,t.exports}a.m=n,e=[],a.O=(r,t,n,o)=>{if(!t){var c=1/0;for(f=0;f<e.length;f++){for(var[t,n,o]=e[f],d=!0,i=0;i<t.length;i++)(!1&o||c>=o)&&Object.keys(a.O).every((e=>a.O[e](t[i])))?t.splice(i--,1):(d=!1,o<c&&(c=o));if(d){e.splice(f--,1);var s=n();void 0!==s&&(r=s)}}return r}o=o||0;for(var f=e.length;f>0&&e[f-1][2]>o;f--)e[f]=e[f-1];e[f]=[t,n,o]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((r,t)=>(a.f[t](e,r),r)),[])),a.u=e=>"js/"+{1084:"profile~followers.bundle",1983:"kb.bundle",2470:"home.chunk",2521:"about.bundle",2530:"discover~myhashtags.chunk",2586:"compose.chunk",2732:"dms~message.chunk",3351:"discover~settings.chunk",3365:"dms.chunk",3623:"discover~findfriends.chunk",4028:"error404.bundle",4509:"static~privacy.bundle",4958:"discover.chunk",4965:"discover~memories.chunk",5865:"post.chunk",6053:"notifications.chunk",6869:"profile.chunk",7004:"help.bundle",7019:"discover~hashtag.bundle",8021:"contact.bundle",8250:"i18n.bundle",8517:"daci.chunk",8600:"changelog.bundle",8625:"profile~following.bundle",8900:"discover~serverfeed.chunk",9144:"static~tos.bundle"}[e]+"."+{1084:"f18a24d3924b651a",1983:"e5709245effd8e20",2470:"64a8f34f10a4fa8b",2521:"a0398e8c630f7036",2530:"ec2c96b72899819b",2586:"f335df0cd85ea00b",2732:"848e25098152c821",3351:"9bac38bba3619276",3365:"37131c41fc288259",3623:"f9f303e4742d4d0e",4028:"6f43a867cb75b343",4509:"c647cbc1674cfea8",4958:"b33cd1cc42853828",4965:"b6fd5951cd01560a",5865:"d7408f11b67053fd",6053:"a310984a7cefe091",6869:"e6ac60336120dcd5",7004:"4157e6be875557da",7019:"7c5f7f5c21a1d88c",8021:"3c0833e75a8155f2",8250:"c5c5f4ddf5b18688",8517:"289add6be0f9f34f",8600:"9ac9432f209bde4e",8625:"8a269b2c4fd0722c",8900:"556f2541edd05a9c",9144:"fc0a2c6ff6297f24"}[e]+".js",a.miniCssF=e=>({138:"css/spa",703:"css/admin",1242:"css/appdark",6170:"css/app",8737:"css/portfolio",9994:"css/landing"}[e]+".css"),a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="pixelfed:",a.l=(e,n,o,c)=>{if(r[e])r[e].push(n);else{var d,i;if(void 0!==o)for(var s=document.getElementsByTagName("script"),f=0;f<s.length;f++){var l=s[f];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==t+o){d=l;break}}d||(i=!0,(d=document.createElement("script")).charset="utf-8",d.timeout=120,a.nc&&d.setAttribute("nonce",a.nc),d.setAttribute("data-webpack",t+o),d.src=e),r[e]=[n];var u=(t,n)=>{d.onerror=d.onload=null,clearTimeout(b);var o=r[e];if(delete r[e],d.parentNode&&d.parentNode.removeChild(d),o&&o.forEach((e=>e(n))),t)return t(n)},b=setTimeout(u.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=u.bind(null,d.onerror),d.onload=u.bind(null,d.onload),i&&document.head.appendChild(d)}},a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),a.p="/",(()=>{var e={8929:0,1242:0,6170:0,8737:0,703:0,9994:0,138:0};a.f.j=(r,t)=>{var n=a.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else if(/^(1242|138|6170|703|8737|8929|9994)$/.test(r))e[r]=0;else{var o=new Promise(((t,o)=>n=e[r]=[t,o]));t.push(n[2]=o);var c=a.p+a.u(r),d=new Error;a.l(c,(t=>{if(a.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var o=t&&("load"===t.type?"missing":t.type),c=t&&t.target&&t.target.src;d.message="Loading chunk "+r+" failed.\n("+o+": "+c+")",d.name="ChunkLoadError",d.type=o,d.request=c,n[1](d)}}),"chunk-"+r,r)}},a.O.j=r=>0===e[r];var r=(r,t)=>{var n,o,[c,d,i]=t,s=0;if(c.some((r=>0!==e[r]))){for(n in d)a.o(d,n)&&(a.m[n]=d[n]);if(i)var f=i(a)}for(r&&r(t);s<c.length;s++)o=c[s],a.o(e,o)&&e[o]&&e[o][0](),e[o]=0;return a.O(f)},t=self.webpackChunkpixelfed=self.webpackChunkpixelfed||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),a.nc=void 0})();
(()=>{"use strict";var e,r,t,n={},o={};function a(e){var r=o[e];if(void 0!==r)return r.exports;var t=o[e]={id:e,loaded:!1,exports:{}};return n[e].call(t.exports,t,t.exports,a),t.loaded=!0,t.exports}a.m=n,e=[],a.O=(r,t,n,o)=>{if(!t){var d=1/0;for(l=0;l<e.length;l++){for(var[t,n,o]=e[l],c=!0,i=0;i<t.length;i++)(!1&o||d>=o)&&Object.keys(a.O).every((e=>a.O[e](t[i])))?t.splice(i--,1):(c=!1,o<d&&(d=o));if(c){e.splice(l--,1);var s=n();void 0!==s&&(r=s)}}return r}o=o||0;for(var l=e.length;l>0&&e[l-1][2]>o;l--)e[l]=e[l-1];e[l]=[t,n,o]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((r,t)=>(a.f[t](e,r),r)),[])),a.u=e=>"js/"+{1084:"profile~followers.bundle",1983:"kb.bundle",2470:"home.chunk",2521:"about.bundle",2530:"discover~myhashtags.chunk",2586:"compose.chunk",2732:"dms~message.chunk",3351:"discover~settings.chunk",3365:"dms.chunk",3623:"discover~findfriends.chunk",4028:"error404.bundle",4509:"static~privacy.bundle",4958:"discover.chunk",4965:"discover~memories.chunk",5865:"post.chunk",6053:"notifications.chunk",6869:"profile.chunk",7004:"help.bundle",7019:"discover~hashtag.bundle",8021:"contact.bundle",8250:"i18n.bundle",8517:"daci.chunk",8600:"changelog.bundle",8625:"profile~following.bundle",8900:"discover~serverfeed.chunk",9144:"static~tos.bundle"}[e]+"."+{1084:"609be992e8222ed8",1983:"275433a4dc3ffda8",2470:"e9544807955a793b",2521:"bad10a127433fdef",2530:"cdc63d8d61ec1688",2586:"377e944cece35cfa",2732:"a69815bfbd4d4598",3351:"1e950f423cfffdee",3365:"4fb5b1ec270b18a1",3623:"bc529a26035305c1",4028:"8aa1c24f3ce999a6",4509:"26054b5ae4c0bed4",4958:"185909b64f3f8f1d",4965:"a2a2d7bc32632a7c",5865:"3ea384fc9ebf43c7",6053:"d0d53f16d9998dd2",6869:"4e79ac3514929747",7004:"bed48f9410486673",7019:"31c30c11f6e84825",8021:"14773b169db68356",8250:"d69fe365e8c72323",8517:"48177e534fb8cf13",8600:"099f13cf06b3200a",8625:"796b720c16682ef9",8900:"deb26bf532866578",9144:"478ba7e3a3536a1b"}[e]+".js",a.miniCssF=e=>({138:"css/spa",703:"css/admin",1242:"css/appdark",6170:"css/app",8737:"css/portfolio",9994:"css/landing"}[e]+".css"),a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="pixelfed:",a.l=(e,n,o,d)=>{if(r[e])r[e].push(n);else{var c,i;if(void 0!==o)for(var s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var f=s[l];if(f.getAttribute("src")==e||f.getAttribute("data-webpack")==t+o){c=f;break}}c||(i=!0,(c=document.createElement("script")).charset="utf-8",c.timeout=120,a.nc&&c.setAttribute("nonce",a.nc),c.setAttribute("data-webpack",t+o),c.src=e),r[e]=[n];var u=(t,n)=>{c.onerror=c.onload=null,clearTimeout(b);var o=r[e];if(delete r[e],c.parentNode&&c.parentNode.removeChild(c),o&&o.forEach((e=>e(n))),t)return t(n)},b=setTimeout(u.bind(null,void 0,{type:"timeout",target:c}),12e4);c.onerror=u.bind(null,c.onerror),c.onload=u.bind(null,c.onload),i&&document.head.appendChild(c)}},a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),a.p="/",(()=>{var e={8929:0,1242:0,6170:0,8737:0,703:0,9994:0,138:0};a.f.j=(r,t)=>{var n=a.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else if(/^(1242|138|6170|703|8737|8929|9994)$/.test(r))e[r]=0;else{var o=new Promise(((t,o)=>n=e[r]=[t,o]));t.push(n[2]=o);var d=a.p+a.u(r),c=new Error;a.l(d,(t=>{if(a.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var o=t&&("load"===t.type?"missing":t.type),d=t&&t.target&&t.target.src;c.message="Loading chunk "+r+" failed.\n("+o+": "+d+")",c.name="ChunkLoadError",c.type=o,c.request=d,n[1](c)}}),"chunk-"+r,r)}},a.O.j=r=>0===e[r];var r=(r,t)=>{var n,o,[d,c,i]=t,s=0;if(d.some((r=>0!==e[r]))){for(n in c)a.o(c,n)&&(a.m[n]=c[n]);if(i)var l=i(a)}for(r&&r(t);s<d.length;s++)o=d[s],a.o(e,o)&&e[o]&&e[o][0](),e[o]=0;return a.O(l)},t=self.webpackChunkpixelfed=self.webpackChunkpixelfed||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),a.nc=void 0})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -25,38 +25,38 @@
"/js/portfolio.js": "/js/portfolio.js?id=4fb6929e78830b1bb71410180b8b2772",
"/js/installer.js": "/js/installer.js?id=cd240ae970947b76ac49032ba95e0922",
"/js/admin_invite.js": "/js/admin_invite.js?id=307a53250701e3b12164af9495e88447",
"/js/manifest.js": "/js/manifest.js?id=7e732abc8a08ae60bb4c853378beac9d",
"/js/home.chunk.64a8f34f10a4fa8b.js": "/js/home.chunk.64a8f34f10a4fa8b.js?id=22be6b9b89134a72225e7b1e2fd08927",
"/js/compose.chunk.f335df0cd85ea00b.js": "/js/compose.chunk.f335df0cd85ea00b.js?id=6389b021170bc21b58fc5bc28920f9af",
"/js/post.chunk.d7408f11b67053fd.js": "/js/post.chunk.d7408f11b67053fd.js?id=654ed8ff06ef863ac47d57d002fac5d5",
"/js/profile.chunk.e6ac60336120dcd5.js": "/js/profile.chunk.e6ac60336120dcd5.js?id=056ff539475910f8596d168ee759cf48",
"/js/discover~memories.chunk.b6fd5951cd01560a.js": "/js/discover~memories.chunk.b6fd5951cd01560a.js?id=8d6c5c36a70eff8f3afb25307f603bd7",
"/js/discover~myhashtags.chunk.ec2c96b72899819b.js": "/js/discover~myhashtags.chunk.ec2c96b72899819b.js?id=73544cfa7b526a2ad9563bfdc7fe4c6e",
"/js/daci.chunk.289add6be0f9f34f.js": "/js/daci.chunk.289add6be0f9f34f.js?id=1c2f0afcb80dc9b627c7900499d5c149",
"/js/discover~findfriends.chunk.f9f303e4742d4d0e.js": "/js/discover~findfriends.chunk.f9f303e4742d4d0e.js?id=45b25ef713a9f2d775bf6b32ca0b56a3",
"/js/discover~serverfeed.chunk.556f2541edd05a9c.js": "/js/discover~serverfeed.chunk.556f2541edd05a9c.js?id=4f8f6e174ca565a61b3b2bbe69965861",
"/js/discover~settings.chunk.9bac38bba3619276.js": "/js/discover~settings.chunk.9bac38bba3619276.js?id=0af79e7702cd1fba672daea02771aed4",
"/js/discover.chunk.b33cd1cc42853828.js": "/js/discover.chunk.b33cd1cc42853828.js?id=6dcffad6c504442e374de397cc711eb6",
"/js/notifications.chunk.a310984a7cefe091.js": "/js/notifications.chunk.a310984a7cefe091.js?id=4b058bc04867e65daa3ca296a05f9797",
"/js/dms.chunk.37131c41fc288259.js": "/js/dms.chunk.37131c41fc288259.js?id=752e3b061c1e76baa73b5d38657bf93e",
"/js/dms~message.chunk.848e25098152c821.js": "/js/dms~message.chunk.848e25098152c821.js?id=bd3b4b71f23988bdfaf09ed817219cb9",
"/js/profile~followers.bundle.f18a24d3924b651a.js": "/js/profile~followers.bundle.f18a24d3924b651a.js?id=a62568f338ddace02455f4d9889bf31f",
"/js/profile~following.bundle.8a269b2c4fd0722c.js": "/js/profile~following.bundle.8a269b2c4fd0722c.js?id=cf1c9e06af5d4013d75b3577dcd237c4",
"/js/discover~hashtag.bundle.7c5f7f5c21a1d88c.js": "/js/discover~hashtag.bundle.7c5f7f5c21a1d88c.js?id=be75e076f14d258c1c581abc07f40af3",
"/js/error404.bundle.6f43a867cb75b343.js": "/js/error404.bundle.6f43a867cb75b343.js?id=a5c557f4d707537aa3f023a0786dfeba",
"/js/help.bundle.4157e6be875557da.js": "/js/help.bundle.4157e6be875557da.js?id=5de97a307e5f3c6f1079fe57ff6f8294",
"/js/kb.bundle.e5709245effd8e20.js": "/js/kb.bundle.e5709245effd8e20.js?id=d1d8c0f2c80a50471e4df88c0bd4ca0d",
"/js/about.bundle.a0398e8c630f7036.js": "/js/about.bundle.a0398e8c630f7036.js?id=55b4ddaae96427389b23ab0dc12d44f0",
"/js/contact.bundle.3c0833e75a8155f2.js": "/js/contact.bundle.3c0833e75a8155f2.js?id=453c2addc6c5a26681505de5a97b252d",
"/js/i18n.bundle.c5c5f4ddf5b18688.js": "/js/i18n.bundle.c5c5f4ddf5b18688.js?id=06abe79741d5b8c93ad8de99edcd928d",
"/js/static~privacy.bundle.c647cbc1674cfea8.js": "/js/static~privacy.bundle.c647cbc1674cfea8.js?id=3384a4144056cbda76c3d4aaab7d5120",
"/js/static~tos.bundle.fc0a2c6ff6297f24.js": "/js/static~tos.bundle.fc0a2c6ff6297f24.js?id=6244cffbba6358ab51dbb877bda682ab",
"/js/changelog.bundle.9ac9432f209bde4e.js": "/js/changelog.bundle.9ac9432f209bde4e.js?id=08c219b93662101da611a8196c6eb763",
"/js/manifest.js": "/js/manifest.js?id=78390c2699bc44f4d137217a24bd52b6",
"/js/home.chunk.e9544807955a793b.js": "/js/home.chunk.e9544807955a793b.js?id=22be6b9b89134a72225e7b1e2fd08927",
"/js/compose.chunk.377e944cece35cfa.js": "/js/compose.chunk.377e944cece35cfa.js?id=6389b021170bc21b58fc5bc28920f9af",
"/js/post.chunk.3ea384fc9ebf43c7.js": "/js/post.chunk.3ea384fc9ebf43c7.js?id=654ed8ff06ef863ac47d57d002fac5d5",
"/js/profile.chunk.4e79ac3514929747.js": "/js/profile.chunk.4e79ac3514929747.js?id=02296964550c97628a032e931e5b77dc",
"/js/discover~memories.chunk.a2a2d7bc32632a7c.js": "/js/discover~memories.chunk.a2a2d7bc32632a7c.js?id=8d6c5c36a70eff8f3afb25307f603bd7",
"/js/discover~myhashtags.chunk.cdc63d8d61ec1688.js": "/js/discover~myhashtags.chunk.cdc63d8d61ec1688.js?id=73544cfa7b526a2ad9563bfdc7fe4c6e",
"/js/daci.chunk.48177e534fb8cf13.js": "/js/daci.chunk.48177e534fb8cf13.js?id=1c2f0afcb80dc9b627c7900499d5c149",
"/js/discover~findfriends.chunk.bc529a26035305c1.js": "/js/discover~findfriends.chunk.bc529a26035305c1.js?id=45b25ef713a9f2d775bf6b32ca0b56a3",
"/js/discover~serverfeed.chunk.deb26bf532866578.js": "/js/discover~serverfeed.chunk.deb26bf532866578.js?id=4f8f6e174ca565a61b3b2bbe69965861",
"/js/discover~settings.chunk.1e950f423cfffdee.js": "/js/discover~settings.chunk.1e950f423cfffdee.js?id=0af79e7702cd1fba672daea02771aed4",
"/js/discover.chunk.185909b64f3f8f1d.js": "/js/discover.chunk.185909b64f3f8f1d.js?id=6dcffad6c504442e374de397cc711eb6",
"/js/notifications.chunk.d0d53f16d9998dd2.js": "/js/notifications.chunk.d0d53f16d9998dd2.js?id=4b058bc04867e65daa3ca296a05f9797",
"/js/dms.chunk.4fb5b1ec270b18a1.js": "/js/dms.chunk.4fb5b1ec270b18a1.js?id=752e3b061c1e76baa73b5d38657bf93e",
"/js/dms~message.chunk.a69815bfbd4d4598.js": "/js/dms~message.chunk.a69815bfbd4d4598.js?id=bd3b4b71f23988bdfaf09ed817219cb9",
"/js/profile~followers.bundle.609be992e8222ed8.js": "/js/profile~followers.bundle.609be992e8222ed8.js?id=a62568f338ddace02455f4d9889bf31f",
"/js/profile~following.bundle.796b720c16682ef9.js": "/js/profile~following.bundle.796b720c16682ef9.js?id=cf1c9e06af5d4013d75b3577dcd237c4",
"/js/discover~hashtag.bundle.31c30c11f6e84825.js": "/js/discover~hashtag.bundle.31c30c11f6e84825.js?id=be75e076f14d258c1c581abc07f40af3",
"/js/error404.bundle.8aa1c24f3ce999a6.js": "/js/error404.bundle.8aa1c24f3ce999a6.js?id=a5c557f4d707537aa3f023a0786dfeba",
"/js/help.bundle.bed48f9410486673.js": "/js/help.bundle.bed48f9410486673.js?id=5de97a307e5f3c6f1079fe57ff6f8294",
"/js/kb.bundle.275433a4dc3ffda8.js": "/js/kb.bundle.275433a4dc3ffda8.js?id=d1d8c0f2c80a50471e4df88c0bd4ca0d",
"/js/about.bundle.bad10a127433fdef.js": "/js/about.bundle.bad10a127433fdef.js?id=55b4ddaae96427389b23ab0dc12d44f0",
"/js/contact.bundle.14773b169db68356.js": "/js/contact.bundle.14773b169db68356.js?id=453c2addc6c5a26681505de5a97b252d",
"/js/i18n.bundle.d69fe365e8c72323.js": "/js/i18n.bundle.d69fe365e8c72323.js?id=06abe79741d5b8c93ad8de99edcd928d",
"/js/static~privacy.bundle.26054b5ae4c0bed4.js": "/js/static~privacy.bundle.26054b5ae4c0bed4.js?id=3384a4144056cbda76c3d4aaab7d5120",
"/js/static~tos.bundle.478ba7e3a3536a1b.js": "/js/static~tos.bundle.478ba7e3a3536a1b.js?id=6244cffbba6358ab51dbb877bda682ab",
"/js/changelog.bundle.099f13cf06b3200a.js": "/js/changelog.bundle.099f13cf06b3200a.js?id=08c219b93662101da611a8196c6eb763",
"/css/appdark.css": "/css/appdark.css?id=de85ecce91d9ed7afa7714547eb1e26c",
"/css/app.css": "/css/app.css?id=88a0a931d5b0e24b0d9355f548414768",
"/css/portfolio.css": "/css/portfolio.css?id=db2c9929a56d83f9ff2aaf2161d29d36",
"/css/admin.css": "/css/admin.css?id=619b6c6613a24e232048856e72110862",
"/css/landing.css": "/css/landing.css?id=681e8ecf284b7cbd1f2b585b2761761d",
"/css/spa.css": "/css/spa.css?id=602c4f74ce800b7bf45a8d8a4d8cb6e5",
"/js/vendor.js": "/js/vendor.js?id=7a1e52ad5031deed20ef6b28241ef679"
"/js/vendor.js": "/js/vendor.js?id=17e05dc4f74c89bb4382c733e132e611"
}

Loading…
Cancel
Save