Merge pull request #666 from pixelfed/frontend-ui-refactor

v0.7.2
pull/676/head
daniel 7 years ago committed by GitHub
commit ddfc868bb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -48,8 +48,8 @@ class FederationController extends Controller
{
$this->authCheck();
$this->validate($request, [
'url' => 'required|string',
]);
'url' => 'required|string',
]);
if (config('pixelfed.remote_follow_enabled') !== true) {
abort(403);
@ -123,16 +123,15 @@ class FederationController extends Controller
{
$this->validate($request, ['resource'=>'required|string|min:3|max:255']);
$hash = hash('sha256', $request->input('resource'));
$webfinger = Cache::remember('api:webfinger:'.$hash, 1440, function () use ($request) {
$resource = $request->input('resource');
$parsed = Nickname::normalizeProfileUrl($resource);
$username = $parsed['username'];
$user = Profile::whereUsername($username)->firstOrFail();
return (new Webfinger($user))->generate();
});
$resource = $request->input('resource');
$hash = hash('sha256', $resource);
$parsed = Nickname::normalizeProfileUrl($resource);
$username = $parsed['username'];
$profile = Profile::whereUsername($username)->firstOrFail();
if($profile->status != null) {
return ProfileController::accountCheck($profile);
}
$webfinger = (new Webfinger($profile))->generate();
return response()->json($webfinger, 200, [], JSON_PRETTY_PRINT);
}
@ -156,13 +155,16 @@ XML;
abort(403);
}
$user = Profile::whereNull('remote_url')->whereUsername($username)->firstOrFail();
if($user->is_private) {
$profile = Profile::whereNull('remote_url')->whereUsername($username)->firstOrFail();
if($profile->status != null) {
return ProfileController::accountCheck($profile);
}
if($profile->is_private) {
return response()->json(['error'=>'403', 'msg' => 'private profile'], 403);
}
$timeline = $user->statuses()->whereVisibility('public')->orderBy('created_at', 'desc')->paginate(10);
$timeline = $profile->statuses()->whereVisibility('public')->orderBy('created_at', 'desc')->paginate(10);
$fractal = new Fractal\Manager();
$resource = new Fractal\Resource\Item($user, new ProfileOutbox());
$resource = new Fractal\Resource\Item($profile, new ProfileOutbox());
$res = $fractal->createData($resource)->toArray();
return response(json_encode($res['data']))->header('Content-Type', 'application/activity+json');
@ -175,6 +177,9 @@ XML;
}
$profile = Profile::whereNull('domain')->whereUsername($username)->firstOrFail();
if($profile->status != null) {
return ProfileController::accountCheck($profile);
}
$body = $request->getContent();
$bodyDecoded = json_decode($body, true);
$signature = $request->header('signature');
@ -205,6 +210,9 @@ XML;
->whereUsername($username)
->whereIsPrivate(false)
->firstOrFail();
if($profile->status != null) {
return ProfileController::accountCheck($profile);
}
$obj = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'id' => $request->getUri(),
@ -226,6 +234,9 @@ XML;
->whereUsername($username)
->whereIsPrivate(false)
->firstOrFail();
if($profile->status != null) {
return ProfileController::accountCheck($profile);
}
$obj = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'id' => $request->getUri(),

@ -37,7 +37,7 @@ class FollowerController extends Controller
protected function handleFollowRequest($item)
{
$user = Auth::user()->profile;
$target = Profile::where('id', '!=', $user->id)->findOrFail($item);
$target = Profile::where('id', '!=', $user->id)->whereNull('status')->findOrFail($item);
$private = (bool) $target->is_private;
$blocked = UserFilter::whereUserId($target->id)
->whereFilterType('block')

@ -112,6 +112,7 @@ class InternalApiController extends Controller
$people = Profile::select('id', 'name', 'username')
->with('avatar')
->whereNull('status')
->orderByRaw('rand()')
->whereHas('statuses')
->whereNull('domain')
@ -206,6 +207,9 @@ class InternalApiController extends Controller
$posts = Status::select('id', 'caption', 'profile_id')
->whereHas('media')
->whereHas('profile', function($q) {
return $q->whereNull('status');
})
->whereIsNsfw(false)
->whereVisibility('public')
->whereNotIn('profile_id', $following)

@ -20,7 +20,11 @@ class ProfileController extends Controller
public function show(Request $request, $username)
{
$user = Profile::whereUsername($username)->firstOrFail();
return $this->buildProfile($request, $user);
if($user->status != null) {
return $this->accountCheck($user);
} else {
return $this->buildProfile($request, $user);
}
}
// TODO: refactor this mess
@ -30,7 +34,11 @@ class ProfileController extends Controller
$loggedIn = Auth::check();
$isPrivate = false;
$isBlocked = false;
if($user->status != null) {
return ProfileController::accountCheck($user);
}
if ($user->remote_url) {
$settings = new \StdClass;
$settings->crawlable = false;
@ -118,8 +126,27 @@ class ProfileController extends Controller
return false;
}
public static function accountCheck(Profile $profile)
{
switch ($profile->status) {
case 'disabled':
case 'delete':
return view('profile.disabled');
break;
default:
# code...
break;
}
return abort(404);
}
public function showActivityPub(Request $request, $user)
{
if($user->status != null) {
return ProfileController::accountCheck($user);
}
$fractal = new Fractal\Manager();
$resource = new Fractal\Resource\Item($user, new ProfileTransformer);
$res = $fractal->createData($resource)->toArray();
@ -129,6 +156,9 @@ class ProfileController extends Controller
public function showAtomFeed(Request $request, $user)
{
$profile = $user = Profile::whereUsername($user)->firstOrFail();
if($profile->status != null) {
return $this->accountCheck($profile);
}
if($profile->is_private || Auth::check()) {
$blocked = $this->blockedProfileCheck($profile);
$check = $this->privateProfileCheck($profile, null);
@ -144,7 +174,9 @@ class ProfileController extends Controller
public function followers(Request $request, $username)
{
$profile = $user = Profile::whereUsername($username)->firstOrFail();
if($profile->status != null) {
return $this->accountCheck($profile);
}
// TODO: fix $profile/$user mismatch in profile & follower templates
$owner = Auth::check() && Auth::id() === $user->user_id;
$is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false;
@ -155,7 +187,7 @@ class ProfileController extends Controller
return view('profile.private', compact('user', 'is_following'));
}
}
$followers = $profile->followers()->orderBy('created_at', 'desc')->simplePaginate(12);
$followers = $profile->followers()->whereNull('status')->orderBy('created_at', 'desc')->simplePaginate(12);
$is_admin = is_null($user->domain) ? $user->user->is_admin : false;
if ($user->remote_url) {
$settings = new \StdClass;
@ -172,6 +204,9 @@ class ProfileController extends Controller
public function following(Request $request, $username)
{
$profile = $user = Profile::whereUsername($username)->firstOrFail();
if($profile->status != null) {
return $this->accountCheck($profile);
}
// TODO: fix $profile/$user mismatch in profile & follower templates
$owner = Auth::check() && Auth::id() === $user->user_id;
$is_following = ($owner == false && Auth::check()) ? $user->followedBy(Auth::user()->profile) : false;
@ -182,7 +217,7 @@ class ProfileController extends Controller
return view('profile.private', compact('user', 'is_following'));
}
}
$following = $profile->following()->orderBy('created_at', 'desc')->simplePaginate(12);
$following = $profile->following()->whereNull('status')->orderBy('created_at', 'desc')->simplePaginate(12);
$is_admin = is_null($user->domain) ? $user->user->is_admin : false;
if ($user->remote_url) {
$settings = new \StdClass;
@ -201,7 +236,10 @@ class ProfileController extends Controller
if (Auth::check() === false || $username !== Auth::user()->username) {
abort(403);
}
$user = Auth::user()->profile;
$user = $profile = Auth::user()->profile;
if($profile->status != null) {
return $this->accountCheck($profile);
}
$settings = User::whereUsername($username)->firstOrFail()->settings;
$owner = true;
$following = false;

@ -43,6 +43,9 @@ class PublicApiController extends Controller
return [];
} else {
$profile = Auth::user()->profile;
if($profile->status) {
return [];
}
$user = new Fractal\Resource\Item($profile, new AccountTransformer());
return $this->fractal->createData($user)->toArray();
}
@ -54,6 +57,9 @@ class PublicApiController extends Controller
return [];
} else {
$profile = Auth::user()->profile;
if($profile->status) {
return [];
}
$likes = $status->likedBy()->orderBy('created_at','desc')->paginate(10);
$collection = new Fractal\Resource\Collection($likes, new AccountTransformer());
return $this->fractal->createData($collection)->toArray();
@ -74,8 +80,8 @@ class PublicApiController extends Controller
public function status(Request $request, $username, int $postid)
{
$profile = Profile::whereUsername($username)->first();
$status = Status::whereProfileId($profile->id)->find($postid);
$profile = Profile::whereUsername($username)->whereNull('status')->firstOrFail();
$status = Status::whereProfileId($profile->id)->findOrFail($postid);
$this->scopeCheck($profile, $status);
$item = new Fractal\Resource\Item($status, new StatusTransformer());
$res = [
@ -100,8 +106,8 @@ class PublicApiController extends Controller
'limit' => 'nullable|integer|min:5|max:50'
]);
$limit = $request->limit ?? 10;
$profile = Profile::whereUsername($username)->first();
$status = Status::whereProfileId($profile->id)->find($postId);
$profile = Profile::whereUsername($username)->whereNull('status')->firstOrFail();
$status = Status::whereProfileId($profile->id)->findOrFail($postId);
$this->scopeCheck($profile, $status);
if($request->filled('min_id') || $request->filled('max_id')) {
if($request->filled('min_id')) {
@ -133,8 +139,8 @@ class PublicApiController extends Controller
public function statusLikes(Request $request, $username, $id)
{
$profile = Profile::whereUsername($username)->first();
$status = Status::whereProfileId($profile->id)->find($id);
$profile = Profile::whereUsername($username)->whereNull('status')->firstOrFail();
$status = Status::whereProfileId($profile->id)->findOrFail($id);
$this->scopeCheck($profile, $status);
$likes = $this->getLikes($status);
return response()->json([
@ -144,8 +150,8 @@ class PublicApiController extends Controller
public function statusShares(Request $request, $username, $id)
{
$profile = Profile::whereUsername($username)->first();
$status = Status::whereProfileId($profile->id)->find($id);
$profile = Profile::whereUsername($username)->whereNull('status')->firstOrFail();
$status = Status::whereProfileId($profile->id)->findOrFail($id);
$this->scopeCheck($profile, $status);
$shares = $this->getShares($status);
return response()->json([
@ -210,7 +216,7 @@ class PublicApiController extends Controller
// $timeline = Timeline::build()->local();
$pid = Auth::user()->profile->id;
$private = Profile::whereIsPrivate(true)->where('id', '!=', $pid)->pluck('id');
$private = Profile::whereIsPrivate(true)->orWhereNotNull('status')->where('id', '!=', $pid)->pluck('id');
$filters = UserFilter::whereUserId($pid)
->whereFilterableType('App\Profile')
->whereIn('filter_type', ['mute', 'block'])
@ -272,7 +278,7 @@ class PublicApiController extends Controller
$following = Follower::whereProfileId($pid)->pluck('following_id');
$following->push($pid)->toArray();
$private = Profile::whereIsPrivate(true)->where('id', '!=', $pid)->pluck('id');
$private = Profile::whereIsPrivate(true)->orWhereNotNull('status')->where('id', '!=', $pid)->pluck('id');
$filters = UserFilter::whereUserId($pid)
->whereFilterableType('App\Profile')
->whereIn('filter_type', ['mute', 'block'])

@ -22,7 +22,7 @@ class SearchController extends Controller
return;
}
$hash = hash('sha256', $tag);
$tokens = Cache::remember('api:search:tag:'.$hash, 60, function () use ($tag) {
$tokens = Cache::remember('api:search:tag:'.$hash, 5, function () use ($tag) {
$tokens = collect([]);
$hashtags = Hashtag::select('id', 'name', 'slug')->where('slug', 'like', '%'.$tag.'%')->limit(20)->get();
if($hashtags->count() > 0) {
@ -39,6 +39,7 @@ class SearchController extends Controller
$tokens->push($tags);
}
$users = Profile::select('username', 'name', 'id')
->whereNull('status')
->where('username', 'like', '%'.$tag.'%')
->limit(20)
->get();

@ -5,10 +5,8 @@ namespace App\Http\Controllers;
use App\AccountLog;
use App\Following;
use App\UserFilter;
use Auth;
use DB;
use Cache;
use Purify;
use Auth, DB, Cache, Purify;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Settings\{
HomeSettings,
@ -137,6 +135,18 @@ class SettingsController extends Controller
return view('settings.remove.temporary');
}
public function removeAccountTemporarySubmit(Request $request)
{
$user = Auth::user();
$profile = $user->profile;
$user->status = 'disabled';
$profile->status = 'disabled';
$user->save();
$profile->save();
Auth::logout();
return redirect('/');
}
public function removeAccountPermanent(Request $request)
{
return view('settings.remove.permanent');
@ -148,7 +158,14 @@ class SettingsController extends Controller
if($user->is_admin == true) {
return abort(400, 'You cannot delete an admin account.');
}
DeleteAccountPipeline::dispatch($user);
$profile = $user->profile;
$ts = Carbon::now()->addMonth();
$user->status = 'delete';
$profile->status = 'delete';
$user->delete_after = $ts;
$profile->delete_after = $ts;
$user->save();
$profile->save();
Auth::logout();
return redirect('/');
}

@ -21,10 +21,22 @@ class StatusController extends Controller
{
$user = Profile::whereUsername($username)->firstOrFail();
if($user->status != null) {
return ProfileController::accountCheck($user);
}
$status = Status::whereProfileId($user->id)
->whereNotIn('visibility',['draft','direct'])
->findOrFail($id);
if($status->uri) {
$url = $status->uri;
if(ends_with($url, '/activity')) {
$url = str_replace('/activity', '', $url);
}
return redirect($url);
}
if($status->visibility == 'private' || $user->is_private) {
if(!Auth::check()) {
abort(403);

@ -37,11 +37,9 @@ class NewStatusPipeline implements ShouldQueue
$status = $this->status;
StatusEntityLexer::dispatch($status);
StatusActivityPubDeliver::dispatch($status);
Cache::forever('post.'.$status->id, $status);
$redis = Redis::connection();
$redis->lpush(config('cache.prefix').':user.'.$status->profile_id.'.posts', $status->id);
// Cache::forever('post.'.$status->id, $status);
// $redis = Redis::connection();
// $redis->lpush(config('cache.prefix').':user.'.$status->profile_id.'.posts', $status->id);
}
}

@ -38,6 +38,10 @@ class StatusActivityPubDeliver implements ShouldQueue
{
$status = $this->status;
if($status->local == true || $status->url || $status->uri) {
return;
}
$audience = $status->profile->getAudienceInbox();
$profile = $status->profile;
@ -49,7 +53,5 @@ class StatusActivityPubDeliver implements ShouldQueue
foreach($audience as $url) {
Helpers::sendSignedObject($profile, $url, $activity);
}
// todo: fanout on write
}
}

@ -42,7 +42,6 @@ class StatusEntityLexer implements ShouldQueue
*/
public function handle()
{
$status = $this->status;
$this->parseEntities();
}
@ -73,6 +72,7 @@ class StatusEntityLexer implements ShouldQueue
$status->entities = json_encode($this->entities);
$status->save();
});
StatusActivityPubDeliver::dispatch($this->status);
}
public function storeHashtags()

@ -61,5 +61,30 @@ class AuthLogin
CreateAvatar::dispatch($profile);
});
}
if($user->status != null) {
$profile = $user->profile;
switch ($user->status) {
case 'disabled':
$profile->status = null;
$user->status = null;
$profile->save();
$user->save();
break;
case 'delete':
$profile->status = null;
$profile->delete_after = null;
$user->status = null;
$user->delete_after = null;
$profile->save();
$user->save();
break;
default:
# code...
break;
}
}
}
}

@ -7,6 +7,7 @@ use App\{
Activity,
Follower,
Like,
Media,
Notification,
Profile,
Status
@ -281,11 +282,11 @@ class Helpers {
public static function profileFirstOrNew($url, $runJobs = false)
{
$res = self::fetchProfileFromUrl($url);
$domain = parse_url($res['url'], PHP_URL_HOST);
$domain = parse_url($res['id'], PHP_URL_HOST);
$username = $res['preferredUsername'];
$remoteUsername = "@{$username}@{$domain}";
$profile = Profile::whereRemoteUrl($res['url'])->first();
$profile = Profile::whereRemoteUrl($res['id'])->first();
if(!$profile) {
$profile = new Profile;
$profile->domain = $domain;
@ -295,7 +296,7 @@ class Helpers {
$profile->sharedInbox = isset($res['endpoints']) && isset($res['endpoints']['sharedInbox']) ? $res['endpoints']['sharedInbox'] : null;
$profile->inbox_url = $res['inbox'];
$profile->outbox_url = $res['outbox'];
$profile->remote_url = $res['url'];
$profile->remote_url = $res['id'];
$profile->public_key = $res['publicKey']['publicKeyPem'];
$profile->key_id = $res['publicKey']['id'];
$profile->save();

@ -32,7 +32,7 @@ class Inbox
public function handle()
{
$this->authenticatePayload();
$this->handleVerb();
}
public function authenticatePayload()
@ -142,16 +142,11 @@ class Inbox
$activity = $this->payload['object'];
$actor = $this->actorFirstOrCreate($this->payload['actor']);
$inReplyTo = $activity['inReplyTo'];
$url = $activity['id'];
if(!Helpers::statusFirstOrFetch($activity['url'], true)) {
$this->logger->delete();
if(!Helpers::statusFirstOrFetch($url, true)) {
return;
}
$this->logger->to_id = $this->profile->id;
$this->logger->from_id = $actor->id;
$this->logger->processed_at = Carbon::now();
$this->logger->save();
}
public function handleNoteCreate()
@ -164,12 +159,11 @@ class Inbox
if(Helpers::userInAudience($this->profile, $this->payload) == false) {
//Log::error('AP:inbox:userInAudience:false - Activity#'.$this->logger->id);
$logger = Activity::find($this->logger->id);
$logger->delete();
return;
}
if(Status::whereUrl($activity['url'])->exists()) {
$url = $activity['id'];
if(Status::whereUrl($url)->exists()) {
return;
}
@ -178,18 +172,12 @@ class Inbox
$status->profile_id = $actor->id;
$status->caption = strip_tags($activity['content']);
$status->visibility = $status->scope = 'public';
$status->url = $activity['url'];
$status->url = $url;
$status->save();
return $status;
});
Helpers::importNoteAttachment($activity, $status);
$logger = Activity::find($this->logger->id);
$logger->to_id = $this->profile->id;
$logger->from_id = $actor->id;
$logger->processed_at = Carbon::now();
$logger->save();
}
public function handleFollowActivity()
@ -214,7 +202,6 @@ class Inbox
'local_profile' => empty($actor->domain)
]);
if($follower->wasRecentlyCreated == false) {
$this->logger->delete();
return;
}
// send notification
@ -228,37 +215,53 @@ class Inbox
$notification->item_type = "App\Profile";
$notification->save();
\Cache::forever('notification.'.$notification->id, $notification);
$redis = Redis::connection();
$nkey = config('cache.prefix').':user.'.$target->id.'.notifications';
$redis->lpush($nkey, $notification->id);
// send Accept to remote profile
$accept = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'id' => $follower->permalink('/accept'),
'id' => $target->permalink().'#accepts/follows/',
'type' => 'Accept',
'actor' => $target->permalink(),
'object' => [
'id' => $this->payload['id'],
'id' => $actor->permalink('#follows/'.$target->id),
'type' => 'Follow',
'actor' => $target->permalink(),
'object' => $actor->permalink()
'actor' => $actor->permalink(),
'object' => $target->permalink()
]
];
Helpers::sendSignedObject($target, $actor->inbox_url, $accept);
}
$this->logger->to_id = $target->id;
$this->logger->from_id = $actor->id;
$this->logger->processed_at = Carbon::now();
$this->logger->save();
}
public function handleAnnounceActivity()
{
$actor = $this->actorFirstOrCreate($this->payload['actor']);
$activity = $this->payload['object'];
if(!$actor || $actor->domain == null) {
return;
}
if(Helpers::validateLocalUrl($activity) == false) {
return;
}
$parent = Helpers::statusFirstOrFetch($activity, true);
if(!$parent) {
return;
}
$status = Status::firstOrCreate([
'profile_id' => $actor->id,
'in_reply_to_id' => $parent->id,
'type' => 'reply'
]);
if($status->wasRecentlyCreated) {
$notification = new Notification();
$notification->profile_id = $parent->profile->id;
$notification->actor_id = $actor->id;
$notification->action = 'comment';
$notification->message = $status->toText();
$notification->rendered = $status->toHtml();
$notification->item_id = $parent->id;
$notification->item_type = "App\Status";
$notification->save();
}
}
public function handleAcceptActivity()
@ -268,7 +271,19 @@ class Inbox
public function handleDeleteActivity()
{
$actor = $this->payload['actor'];
$obj = $this->payload['object'];
if(is_string($obj) && Helpers::validateUrl($obj)) {
// actor object detected
} else if (is_array($obj) && isset($obj['type']) && $obj['type'] == 'Tombstone') {
// tombstone detected
$status = Status::whereUri($obj['id'])->first();
if($status == null) {
return;
}
$status->forceDelete();
}
}
public function handleLikeActivity()
@ -289,10 +304,6 @@ class Inbox
return;
}
LikePipeline::dispatch($like);
$this->logger->to_id = $status->profile_id;
$this->logger->from_id = $profile->id;
$this->logger->processed_at = Carbon::now();
$this->logger->save();
}
@ -306,19 +317,29 @@ class Inbox
$actor = $this->payload['actor'];
$profile = self::actorFirstOrCreate($actor);
$obj = $this->payload['object'];
$status = Helpers::statusFirstOrFetch($obj['object']);
switch ($obj['type']) {
case 'Like':
$status = Helpers::statusFirstOrFetch($obj['object']);
Like::whereProfileId($profile->id)
->whereStatusId($status->id)
->delete();
->forceDelete();
break;
case 'Announce':
$parent = Helpers::statusFirstOrFetch($obj['object']);
$status = Status::whereProfileId($profile->id)
->whereReblogOfId($parent->id)
->first();
Notification::whereProfileId($parent->profile->id)
->whereActorId($profile->id)
->whereAction('share')
->whereItemId($status->id)
->whereItemType('App\Status')
->forceDelete();
$status->forceDelete();
break;
}
$this->logger->to_id = $status->profile_id;
$this->logger->from_id = $profile->id;
$this->logger->processed_at = Carbon::now();
$this->logger->save();
}
}

@ -0,0 +1,40 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddDeleteAfterToUserTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('profiles', function (Blueprint $table) {
$table->timestamp('delete_after')->nullable();
});
Schema::table('users', function (Blueprint $table) {
$table->timestamp('delete_after')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('profiles', function (Blueprint $table) {
$table->dropColumn('delete_after');
});
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('delete_after');
});
}
}

245
package-lock.json generated

@ -104,11 +104,15 @@
"json-schema-traverse": "^0.3.0"
}
},
"ajv-errors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
"integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ=="
},
"ajv-keywords": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
"integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
"dev": true
"integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo="
},
"align-text": {
"version": "0.1.4",
@ -164,7 +168,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@ -199,7 +202,6 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
@ -632,6 +634,11 @@
"babel-types": "^6.24.1"
}
},
"babel-helper-vue-jsx-merge-props": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
"integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
},
"babel-helpers": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
@ -1243,8 +1250,7 @@
"big.js": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
"dev": true
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q=="
},
"binary-extensions": {
"version": "1.11.0",
@ -1253,9 +1259,9 @@
"dev": true
},
"blob": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
"integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE="
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
"integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
},
"block-stream": {
"version": "0.0.9",
@ -1328,9 +1334,9 @@
}
},
"bootstrap": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.3.tgz",
"integrity": "sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w=="
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.2.1.tgz",
"integrity": "sha512-tt/7vIv3Gm2mnd/WeDx36nfGGHleil0Wg8IeB7eMrVkY0fZ5iTaBisSh8oNANc2IBsCc6vCgCNTIM/IEN0+50Q=="
},
"bootstrap-vue": {
"version": "2.0.0-rc.11",
@ -1651,7 +1657,6 @@
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@ -1884,7 +1889,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
@ -1892,8 +1896,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "0.3.0",
@ -2123,7 +2126,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz",
"integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==",
"dev": true,
"requires": {
"is-directory": "^0.3.1",
"js-yaml": "^3.9.0",
@ -2134,14 +2136,12 @@
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"js-yaml": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
"integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@ -2151,7 +2151,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
"dev": true,
"requires": {
"error-ex": "^1.3.1",
"json-parse-better-errors": "^1.0.1"
@ -2842,11 +2841,72 @@
"minimalistic-crypto-utils": "^1.0.0"
}
},
"emoji-mart-vue": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/emoji-mart-vue/-/emoji-mart-vue-2.6.6.tgz",
"integrity": "sha512-844CI/Sa99G6goiZN6u+zT5XxB4wUhpYYTK8s3FrU2fl9y0ckbqe0uw7EuY0R53hb4bo9uJHVOPywE+C4vu4fg==",
"requires": {
"postcss-loader": "^3.0.0"
},
"dependencies": {
"ajv": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz",
"integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==",
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"postcss": {
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
"integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
"requires": {
"chalk": "^2.4.1",
"source-map": "^0.6.1",
"supports-color": "^5.5.0"
}
},
"postcss-loader": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
"integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==",
"requires": {
"loader-utils": "^1.1.0",
"postcss": "^7.0.0",
"postcss-load-config": "^2.0.0",
"schema-utils": "^1.0.0"
}
},
"schema-utils": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
"requires": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
"ajv-keywords": "^3.1.0"
}
}
}
},
"emojis-list": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
"integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
"dev": true
"integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k="
},
"encodeurl": {
"version": "1.0.2",
@ -2872,9 +2932,9 @@
}
},
"engine.io-client": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz",
"integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==",
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.1.tgz",
"integrity": "sha512-q66JBFuQcy7CSlfAz9L3jH+v7DTT3i6ZEadYcVj2pOs8/0uJHLxKX3WBkGTvULJMdz0tUCyJag0aKT/dpXL9BQ==",
"requires": {
"component-emitter": "1.2.1",
"component-inherit": "0.0.3",
@ -2884,20 +2944,20 @@
"indexof": "0.0.1",
"parseqs": "0.0.5",
"parseuri": "0.0.5",
"ws": "~3.3.1",
"ws": "~6.1.0",
"xmlhttprequest-ssl": "~1.5.4",
"yeast": "0.1.2"
}
},
"engine.io-parser": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz",
"integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==",
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz",
"integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
"requires": {
"after": "0.8.2",
"arraybuffer.slice": "~0.0.7",
"base64-arraybuffer": "0.1.5",
"blob": "0.0.4",
"blob": "0.0.5",
"has-binary2": "~1.0.2"
}
},
@ -2926,7 +2986,6 @@
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
"requires": {
"is-arrayish": "^0.2.1"
}
@ -3458,8 +3517,7 @@
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
"dev": true
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"fastparse": {
"version": "1.1.1",
@ -4563,8 +4621,7 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-unicode": {
"version": "2.0.1",
@ -4945,7 +5002,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
"integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
"dev": true,
"requires": {
"import-from": "^2.1.0"
}
@ -4954,7 +5010,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
"integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
"dev": true,
"requires": {
"resolve-from": "^3.0.0"
}
@ -5141,8 +5196,7 @@
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
"dev": true
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
},
"is-binary-path": {
"version": "1.0.1",
@ -5222,8 +5276,7 @@
"is-directory": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
"dev": true
"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE="
},
"is-dotfile": {
"version": "1.0.3",
@ -5477,8 +5530,7 @@
"json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
"dev": true
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
},
"json-schema": {
"version": "0.2.3",
@ -5507,8 +5559,7 @@
"json5": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
"dev": true
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
},
"jsonfile": {
"version": "3.0.1",
@ -5544,9 +5595,9 @@
"dev": true
},
"laravel-echo": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.4.0.tgz",
"integrity": "sha512-O0vkToCCpxuH9dYAlugTLQzG0BmxvGrjXim0LHZ0VPsFu/Y+sXnV9GvYbmcBq1rcJymQc/6GHMUCDY01lN26lQ=="
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-1.5.2.tgz",
"integrity": "sha512-Xw9QsxJKapv0C2UTnXRRIM1+epL3+qaSRGd7V8pXEuIHnxjcdpk2I7YLauDzYhBNMKEKWtlE/sv9Wgs+hYKnbg=="
},
"laravel-mix": {
"version": "2.1.14",
@ -5638,7 +5689,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
"integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
"dev": true,
"requires": {
"big.js": "^3.1.3",
"emojis-list": "^2.0.0",
@ -6642,6 +6692,11 @@
}
}
},
"opencollective-postinstall": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.1.tgz",
"integrity": "sha512-saQQ9hjLwu/oS0492eyYotoh+bra1819cfAT5rjY/e4REWwuc8IgZ844Oo44SiftWcJuBiqp0SA0BFVbmLX0IQ=="
},
"opn": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
@ -6964,9 +7019,9 @@
}
},
"popper.js": {
"version": "1.14.4",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.4.tgz",
"integrity": "sha1-juwdj/AqWjoVLdQ0FKFce3n9abY="
"version": "1.14.6",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.6.tgz",
"integrity": "sha512-AGwHGQBKumlk/MDfrSOf0JHhJCImdDMcGNoqKmKkU+68GFazv3CQ6q9r7Ja1sKDZmYWTckY/uLyEznheTDycnA=="
},
"portfinder": {
"version": "1.0.17",
@ -7662,7 +7717,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz",
"integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==",
"dev": true,
"requires": {
"cosmiconfig": "^4.0.0",
"import-cwd": "^2.0.0"
@ -9591,8 +9645,7 @@
"require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
},
"require-main-filename": {
"version": "1.0.1",
@ -9627,8 +9680,7 @@
"resolve-from": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
"dev": true
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
},
"resolve-url": {
"version": "0.2.1",
@ -9759,7 +9811,8 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
},
"safe-regex": {
"version": "1.1.0",
@ -10208,30 +10261,30 @@
}
},
"socket.io-client": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz",
"integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz",
"integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==",
"requires": {
"backo2": "1.0.2",
"base64-arraybuffer": "0.1.5",
"component-bind": "1.0.0",
"component-emitter": "1.2.1",
"debug": "~3.1.0",
"engine.io-client": "~3.2.0",
"engine.io-client": "~3.3.1",
"has-binary2": "~1.0.2",
"has-cors": "1.1.0",
"indexof": "0.0.1",
"object-component": "0.0.3",
"parseqs": "0.0.5",
"parseuri": "0.0.5",
"socket.io-parser": "~3.2.0",
"socket.io-parser": "~3.3.0",
"to-array": "0.1.4"
}
},
"socket.io-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz",
"integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
"integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
"requires": {
"component-emitter": "1.2.1",
"debug": "~3.1.0",
@ -10307,8 +10360,7 @@
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"source-map-resolve": {
"version": "0.5.2",
@ -10441,8 +10493,7 @@
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"sshpk": {
"version": "1.14.2",
@ -10636,7 +10687,6 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
@ -10657,9 +10707,9 @@
}
},
"sweetalert": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.0.tgz",
"integrity": "sha512-9YKj0SvjKyBfRWco50UOsIbXVeifYbxzT9Qda7EsqC01eafHGCSG0IR7g942ufjzt7lnwO8ZZBwr6emXv2fQrg==",
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.2.tgz",
"integrity": "sha512-iWx7X4anRBNDa/a+AdTmvAzQtkN1+s4j/JJRWlHpYE8Qimkohs8/XnFcWeYHH2lMA8LRCa5tj2d244If3S/hzA==",
"requires": {
"es6-object-assign": "^1.1.0",
"promise-polyfill": "^6.0.2"
@ -10989,11 +11039,6 @@
}
}
},
"ultron": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
},
"union-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
@ -11127,7 +11172,6 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
},
@ -11135,8 +11179,7 @@
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
}
}
},
@ -11263,11 +11306,19 @@
}
},
"vue": {
"version": "2.5.17",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.5.17.tgz",
"integrity": "sha512-mFbcWoDIJi0w0Za4emyLiW72Jae0yjANHbCVquMKijcavBGypqlF7zHRgMa5k4sesdv7hv2rB4JPdZfR+TPfhQ==",
"version": "2.5.21",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.5.21.tgz",
"integrity": "sha512-Aejvyyfhn0zjVeLvXd70h4hrE4zZDx1wfZqia6ekkobLmUZ+vNFQer53B4fu0EjWBSiqApxPejzkO1Znt3joxQ==",
"dev": true
},
"vue-content-loader": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/vue-content-loader/-/vue-content-loader-0.2.1.tgz",
"integrity": "sha1-DrMy4qcmQ9V/sgnXLWUmVzsZH1o=",
"requires": {
"babel-helper-vue-jsx-merge-props": "^2.0.3"
}
},
"vue-functional-data-merge": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-2.0.7.tgz",
@ -11347,9 +11398,9 @@
}
},
"vue-loading-overlay": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/vue-loading-overlay/-/vue-loading-overlay-3.1.0.tgz",
"integrity": "sha512-EJOaqxfkSwt6LRoKYnWWPch6fLRRzHWFxLBnRHjXHIK/fP0MSmbBLh9ZRpxarXJeDBiyykQevDXa7h7809JaAA=="
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/vue-loading-overlay/-/vue-loading-overlay-3.1.1.tgz",
"integrity": "sha512-6Iv0V/S++/LDRR3bgIZDJwBTgMVupuj+hjDb2YzTrEXbSEygtD10eJwZdMnEenLcD3ZAFz5D30qkNUYow9W2kw=="
},
"vue-style-loader": {
"version": "3.1.2",
@ -11362,9 +11413,9 @@
}
},
"vue-template-compiler": {
"version": "2.5.17",
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.5.17.tgz",
"integrity": "sha512-63uI4syCwtGR5IJvZM0LN5tVsahrelomHtCxvRkZPJ/Tf3ADm1U1wG6KWycK3qCfqR+ygM5vewUvmJ0REAYksg==",
"version": "2.5.21",
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.5.21.tgz",
"integrity": "sha512-Vmk5Cv7UcmI99B9nXJEkaK262IQNnHp5rJYo+EwYpe2epTAXqcVyExhV6pk8jTkxQK2vRc8v8KmZBAwdmUZvvw==",
"dev": true,
"requires": {
"de-indent": "^1.0.2",
@ -11747,13 +11798,11 @@
"dev": true
},
"ws": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz",
"integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==",
"requires": {
"async-limiter": "~1.0.0",
"safe-buffer": "~5.1.0",
"ultron": "~1.1.0"
"async-limiter": "~1.0.0"
}
},
"xmlhttprequest": {

@ -12,29 +12,32 @@
},
"devDependencies": {
"axios": "^0.18",
"bootstrap": "^4.1.3",
"bootstrap": "^4.2.1",
"cross-env": "^5.2.0",
"jquery": "^3.2",
"laravel-mix": "^2.1.14",
"lodash": "^4.17.11",
"popper.js": "^1.14.4",
"vue": "^2.5.17"
"popper.js": "^1.14.6",
"vue": "^2.5.21",
"vue-template-compiler": "^2.5.21"
},
"dependencies": {
"bootstrap-vue": "^2.0.0-rc.11",
"emoji-mart-vue": "^2.6.6",
"filesize": "^3.6.1",
"infinite-scroll": "^3.0.4",
"laravel-echo": "^1.4.0",
"laravel-echo": "^1.5.2",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.1",
"plyr": "^3.4.7",
"pusher-js": "^4.2.2",
"readmore-js": "^2.2.1",
"socket.io-client": "^2.1.1",
"sweetalert": "^2.1.0",
"socket.io-client": "^2.2.0",
"sweetalert": "^2.1.2",
"twitter-text": "^2.0.5",
"vue-content-loader": "^0.2.1",
"vue-infinite-loading": "^2.4.3",
"vue-loading-overlay": "^3.1.0",
"vue-loading-overlay": "^3.1.1",
"vue-timeago": "^5.0.0"
},
"collective": {

File diff suppressed because one or more lines are too long

2
public/js/app.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,7 +1,7 @@
{
"/js/components.js": "/js/components.js?id=8998b5c828642646b512",
"/js/app.js": "/js/app.js?id=763d01bb175be69c8ad3",
"/css/app.css": "/css/app.css?id=986cee6cfca852babf8e",
"/js/components.js": "/js/components.js?id=29cbe1102d14e648aea7",
"/js/app.js": "/js/app.js?id=4721785cceb8eacd55f1",
"/css/app.css": "/css/app.css?id=c477745c80d3370e7b29",
"/js/timeline.js": "/js/timeline.js?id=415bfde862ab8c5b4548",
"/js/activity.js": "/js/activity.js?id=723dfb98bbbc96a9d39f"
}

@ -2,7 +2,7 @@ window.Vue = require('vue');
import BootstrapVue from 'bootstrap-vue'
import InfiniteLoading from 'vue-infinite-loading';
import Loading from 'vue-loading-overlay';
import VueTimeago from 'vue-timeago'
import VueTimeago from 'vue-timeago';
Vue.use(BootstrapVue);
Vue.use(InfiniteLoading);
@ -36,8 +36,8 @@ require('./components/commentform');
require('./components/searchform');
require('./components/bookmarkform');
require('./components/statusform');
require('./components/embed');
require('./components/notifications');
//require('./components/embed');
//require('./components/notifications');
// import Echo from "laravel-echo"
@ -78,12 +78,16 @@ Vue.component(
require('./components/presenter/VideoAlbumPresenter.vue')
);
Vue.component(
'mixed-album-presenter',
require('./components/presenter/MixedAlbumPresenter.vue')
);
// Vue.component(
// 'micro',
// require('./components/Micro.vue')
// );
Vue.component(
'follow-suggestions',
require('./components/FollowSuggestions.vue')
@ -114,11 +118,6 @@ Vue.component(
require('./components/Timeline.vue')
);
// Vue.component(
// 'micro',
// require('./components/Micro.vue')
// );
Vue.component(
'passport-clients',
require('./components/passport/Clients.vue')

@ -3,7 +3,9 @@
<div class="row">
<div class="col-md-8 col-lg-8 pt-2 px-0 my-3 timeline order-2 order-md-1">
<div class="loader text-center">
<div class="lds-ring"><div></div><div></div><div></div><div></div></div>
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<div class="card mb-4 status-card card-md-rounded-0" :data-status-id="status.id" v-for="(status, index) in feed" :key="status.id">
@ -101,7 +103,9 @@
<div class="mb-4">
<div class="card profile-card">
<div class="card-body loader text-center">
<div class="lds-ring"><div></div><div></div><div></div><div></div></div>
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<div class="card-body contents d-none">
<div class="media d-flex align-items-center">
@ -142,7 +146,9 @@
</p>
</div>
<div class="card-body loader text-center" style="height: 300px;">
<div class="lds-ring"><div></div><div></div><div></div><div></div></div>
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<div class="card-body pt-2 contents" style="max-height: 300px; overflow-y: scroll;">
<div class="media mb-3 align-items-center" v-for="(n, index) in notifications">

@ -9,4 +9,7 @@ return [
'privateProfileWarning' => 'This Account is Private',
'alreadyFollow' => 'Already follow :username?',
'loginToSeeProfile' => 'to see their photos and videos.',
'status.disabled.header' => 'Profile Unavailable',
'status.disabled.body' => 'Sorry, this profile is not available at the moment. Please try again shortly.',
];

@ -0,0 +1,18 @@
@extends('layouts.app',['title' => "Account Temporarily Unavailable"])
@section('content')
<div class="container">
<div class="profile-timeline mt-2 mt-md-4">
<div class="alert alert-danger">
<div class="py-2">
<p class="lead font-weight-bold mb-0">
{{__('profile.status.disabled.header')}}
</p>
<p class="mb-0">
{{__('profile.status.disabled.body')}}
</p>
</div>
</div>
</div>
</div>
@endsection

@ -82,8 +82,9 @@
</div>
<hr>
<div class="form-group row">
<div class="col-12 text-right">
<button type="submit" class="btn btn-primary font-weight-bold">Submit</button>
<div class="col-12 d-flex align-items-center justify-content-between">
<a class="font-weight-bold" href="{{route('settings.remove.temporary')}}">Temporarily Disable Account</a>
<button type="submit" class="btn btn-primary font-weight-bold float-right">Submit</button>
</div>
</div>
</form>

@ -22,7 +22,7 @@
<p>
<form method="post">
@csrf
<div class="custom-control custom-checkbox mb-3">
<div class="custom-control custom-switch mb-3">
<input type="checkbox" class="custom-control-input" id="confirm-check">
<label class="custom-control-label font-weight-bold" for="confirm-check">I confirm that this action is not reversible, and will result in the permanent deletion of my account.</label>
</div>

@ -0,0 +1,30 @@
@extends('settings.template')
@section('section')
<div class="title">
<h3 class="font-weight-bold">Temporarily Disable Your Account</h3>
</div>
<hr>
<div class="mt-3">
<p>Hi <span class="font-weight-bold">{{Auth::user()->username}}</span>,</p>
<p>You can disable your account instead of deleting it. This means your account will be hidden until you reactivate it by logging back in.</p>
<p class="pb-1">You can only disable your account once a week.</p>
<p class="font-weight-bold">Keeping Your Data Safe</p>
<p class="pb-3">Nothing is more important to us than the safety and security of this community. People put their trust in us by sharing moments of their lives on Pixelfed. So we will never make any compromises when it comes to safeguarding your data.</p>
<p class="pb-2">When you press the button below, your photos, comments and likes will be hidden until you reactivate your account by logging back in.</p>
<p>
<form method="post">
@csrf
<button type="submit" class="btn btn-primary font-weight-bold py-0">Temporarily Disable Account</button>
</form>
</p>
</div>
@endsection

@ -12,3 +12,5 @@ use Illuminate\Http\Request;
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::post('/users/{username}/inbox', 'FederationController@userInbox');

@ -76,6 +76,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
Route::post('follow', 'FollowerController@store')->middleware('throttle:250,1440');
Route::post('bookmark', 'BookmarkController@store')->middleware('throttle:250,1440');
Route::get('lang/{locale}', 'SiteController@changeLocale');
Route::get('restored', 'AccountController@accountRestored');
Route::get('verify-email', 'AccountController@verifyEmail');
Route::post('verify-email', 'AccountController@sendVerifyEmail')->middleware('throttle:10,1440');
@ -133,12 +134,12 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
Route::get('privacy/blocked-instances', 'SettingsController@blockedInstances')->name('settings.privacy.blocked-instances');
// Todo: Release in 0.7.2
// Route::group(['prefix' => 'remove', 'middleware' => 'dangerzone'], function() {
// Route::get('request/temporary', 'SettingsController@removeAccountTemporary')->name('settings.remove.temporary');
// Route::post('request/temporary', 'SettingsController@removeAccountTemporarySubmit');
// Route::get('request/permanent', 'SettingsController@removeAccountPermanent')->name('settings.remove.permanent');
// Route::post('request/permanent', 'SettingsController@removeAccountPermanentSubmit');
// });
Route::group(['prefix' => 'remove', 'middleware' => 'dangerzone'], function() {
Route::get('request/temporary', 'SettingsController@removeAccountTemporary')->name('settings.remove.temporary');
Route::post('request/temporary', 'SettingsController@removeAccountTemporarySubmit');
Route::get('request/permanent', 'SettingsController@removeAccountPermanent')->name('settings.remove.permanent');
Route::post('request/permanent', 'SettingsController@removeAccountPermanentSubmit');
});
Route::group(['prefix' => 'security', 'middleware' => 'dangerzone'], function() {
Route::get(

Loading…
Cancel
Save