Jelajahi Sumber

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

Frontend ui refactor
daniel 6 tahun lalu
induk
melakukan
fb5b41d6a2
31 mengubah file dengan 53 tambahan dan 1632 penghapusan
  1. 29 0
      app/Http/Controllers/AvatarController.php
  2. 4 1
      app/Jobs/AvatarPipeline/AvatarOptimize.php
  3. 1 62
      app/Jobs/AvatarPipeline/CreateAvatar.php
  4. 0 94
      app/Util/ActivityPub/Concern/HTTPSignature.php
  5. 0 136
      app/Util/ActivityPub/Writer/BaseWriter.php
  6. 0 34
      app/Util/HTTPSignatures/Algorithm.php
  7. 0 7
      app/Util/HTTPSignatures/AlgorithmException.php
  8. 0 19
      app/Util/HTTPSignatures/AlgorithmInterface.php
  9. 0 119
      app/Util/HTTPSignatures/Context.php
  10. 0 7
      app/Util/HTTPSignatures/Exception.php
  11. 0 41
      app/Util/HTTPSignatures/GuzzleHttpSignatures.php
  12. 0 48
      app/Util/HTTPSignatures/HeaderList.php
  13. 0 36
      app/Util/HTTPSignatures/HmacAlgorithm.php
  14. 0 260
      app/Util/HTTPSignatures/Key.php
  15. 0 7
      app/Util/HTTPSignatures/KeyException.php
  16. 0 36
      app/Util/HTTPSignatures/KeyStore.php
  17. 0 7
      app/Util/HTTPSignatures/KeyStoreException.php
  18. 0 15
      app/Util/HTTPSignatures/KeyStoreInterface.php
  19. 0 64
      app/Util/HTTPSignatures/RsaAlgorithm.php
  20. 0 38
      app/Util/HTTPSignatures/Signature.php
  21. 0 49
      app/Util/HTTPSignatures/SignatureParameters.php
  22. 0 111
      app/Util/HTTPSignatures/SignatureParametersParser.php
  23. 0 7
      app/Util/HTTPSignatures/SignatureParseException.php
  24. 0 7
      app/Util/HTTPSignatures/SignedHeaderNotPresentException.php
  25. 0 104
      app/Util/HTTPSignatures/Signer.php
  26. 0 89
      app/Util/HTTPSignatures/SigningString.php
  27. 0 202
      app/Util/HTTPSignatures/Verification.php
  28. 0 31
      app/Util/HTTPSignatures/Verifier.php
  29. 18 1
      resources/views/settings/home.blade.php
  30. 1 0
      routes/web.php
  31. TEMPAT SAMPAH
      storage/app/public/avatars/default.png

+ 29 - 0
app/Http/Controllers/AvatarController.php

@@ -96,4 +96,33 @@ class AvatarController extends Controller
 
         return $avatarpath;
     }
+
+    public function deleteAvatar(Request $request)
+    {
+        $user = Auth::user();
+        $profile = $user->profile;
+
+        $avatar = $profile->avatar;
+
+        if($avatar->media_path == 'public/avatars/default.png' || $avatar->thumb_path == 'public/avatars/default.png') {
+            return;
+        }
+
+        if(is_file(storage_path('app/' . $avatar->media_path))) {
+            @unlink(storage_path('app/' . $avatar->media_path));
+        }
+
+        if(is_file(storage_path('app/' . $avatar->thumb_path))) {
+            @unlink(storage_path('app/' . $avatar->thumb_path));
+        }
+
+        $avatar->media_path = 'public/avatars/default.png';
+        $avatar->thumb_path = 'public/avatars/default.png';
+        $avatar->change_count = $avatar->change_count + 1;
+        $avatar->save();
+
+        Cache::forget('avatar:' . $avatar->profile_id);
+
+        return response()->json(200);
+    }
 }

+ 4 - 1
app/Jobs/AvatarPipeline/AvatarOptimize.php

@@ -2,6 +2,7 @@
 
 namespace App\Jobs\AvatarPipeline;
 
+use Cache;
 use App\Avatar;
 use App\Profile;
 use Carbon\Carbon;
@@ -10,6 +11,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Foundation\Bus\Dispatchable;
 use Illuminate\Queue\InteractsWithQueue;
 use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Str;
 use Image as Intervention;
 
 class AvatarOptimize implements ShouldQueue
@@ -60,6 +62,7 @@ class AvatarOptimize implements ShouldQueue
             $avatar->change_count = ++$avatar->change_count;
             $avatar->last_processed_at = Carbon::now();
             $avatar->save();
+            Cache::forget('avatar:' . $avatar->profile_id);
             $this->deleteOldAvatar($avatar->media_path, $this->current);
         } catch (Exception $e) {
         }
@@ -67,7 +70,7 @@ class AvatarOptimize implements ShouldQueue
 
     protected function deleteOldAvatar($new, $current)
     {
-        if (storage_path('app/'.$new) == $current || $current == 'public/avatars/default.png') {
+        if (storage_path('app/'.$new) == $current || Str::endsWith($current, 'avatars/default.png')) {
             return;
         }
         if (is_file($current)) {

+ 1 - 62
app/Jobs/AvatarPipeline/CreateAvatar.php

@@ -4,10 +4,6 @@ namespace App\Jobs\AvatarPipeline;
 
 use App\Avatar;
 use App\Profile;
-use App\Util\Identicon\Preprocessor\HashPreprocessor;
-use Bitverse\Identicon\Color\Color;
-use Bitverse\Identicon\Generator\RingsGenerator;
-use Bitverse\Identicon\Identicon;
 use Illuminate\Bus\Queueable;
 use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Foundation\Bus\Dispatchable;
@@ -45,64 +41,7 @@ class CreateAvatar implements ShouldQueue
     public function handle()
     {
         $profile = $this->profile;
-        $username = $profile->username;
-
-        $generator = new RingsGenerator();
-        $generator->setBackgroundColor(Color::parseHex('#FFFFFF'));
-
-        $identicon = new Identicon(new HashPreprocessor('sha256'), $generator);
-
-        $hash = $username.str_random(12);
-        $icon = $identicon->getIcon($hash);
-
-        try {
-            $baseDir = storage_path('app/public/avatars');
-            if (!is_dir($baseDir)) {
-                mkdir($baseDir);
-            }
-
-            $prefix = $profile->id;
-            $padded = str_pad($prefix, 12, 0, STR_PAD_LEFT);
-            $parts = str_split($padded, 3);
-            foreach ($parts as $k => $part) {
-                if ($k == 0) {
-                    $prefix = storage_path('app/public/avatars/'.$parts[0]);
-                    if (!is_dir($prefix)) {
-                        mkdir($prefix);
-                    }
-                }
-                if ($k == 1) {
-                    $prefix = storage_path('app/public/avatars/'.$parts[0].'/'.$parts[1]);
-                    if (!is_dir($prefix)) {
-                        mkdir($prefix);
-                    }
-                }
-                if ($k == 2) {
-                    $prefix = storage_path('app/public/avatars/'.$parts[0].'/'.$parts[1].'/'.$parts[2]);
-                    if (!is_dir($prefix)) {
-                        mkdir($prefix);
-                    }
-                }
-                if ($k == 3) {
-                    $avatarpath = 'public/avatars/'.$parts[0].'/'.$parts[1].'/'.$parts[2].'/'.$parts[3];
-                    $prefix = storage_path('app/'.$avatarpath);
-                    if (!is_dir($prefix)) {
-                        mkdir($prefix);
-                    }
-                }
-            }
-            $dir = storage_path('app/'.$avatarpath);
-            //$dir = storage_path('app/public/avatars/'.$prefix);
-            if (!is_dir($dir)) {
-                mkdir($dir);
-            }
-            //$path = 'public/avatars/' . $prefix . '/avatar.svg';
-            $path = $avatarpath.'/avatar.svg';
-            $basePath = storage_path('app/'.$path);
-            file_put_contents($basePath, $icon);
-        } catch (Exception $e) {
-        }
-
+        $path = 'public/avatars/default.png';
         $avatar = new Avatar();
         $avatar->profile_id = $profile->id;
         $avatar->media_path = $path;

+ 0 - 94
app/Util/ActivityPub/Concern/HTTPSignature.php

@@ -1,94 +0,0 @@
-<?php
-
-namespace App\Util\ActivityPub\Concern;
-
-use Zttp\Zttp;
-
-class HTTPSignature
-{
-    protected $localhosts = [
-      '127.0.0.1', 'localhost', '::1',
-    ];
-    public $profile;
-    public $is_url;
-
-    public function validateUrl()
-    {
-        // If the profile exists, assume its valid
-        if ($this->is_url === false) {
-            return true;
-        }
-
-        $url = $this->profile;
-
-        try {
-            $url = filter_var($url, FILTER_VALIDATE_URL);
-            $parsed = parse_url($url, PHP_URL_HOST);
-            if (!$parsed || in_array($parsed, $this->localhosts)) {
-                return false;
-            }
-        } catch (Exception $e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public function fetchPublicKey($profile, bool $is_url = true)
-    {
-        $this->profile = $profile;
-        $this->is_url = $is_url;
-        $valid = $this->validateUrl();
-        if (!$valid) {
-            throw new \Exception('Invalid URL provided');
-        }
-        if ($is_url && isset($profile->public_key) && $profile->public_key) {
-            return $profile->public_key;
-        }
-
-        try {
-            $url = $this->profile;
-            $res = Zttp::timeout(30)->withHeaders([
-              'Accept'     => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
-              'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org',
-            ])->get($url);
-            $actor = json_decode($res->getBody(), true);
-        } catch (Exception $e) {
-            throw new Exception('Unable to fetch public key');
-        }
-
-        return $actor['publicKey']['publicKeyPem'];
-    }
-
-    public function sendSignedObject($senderProfile, $url, $body)
-    {
-        $profile = $senderProfile;
-        $context = new Context([
-            'keys'      => [$profile->keyId() => $profile->private_key],
-            'algorithm' => 'rsa-sha256',
-            'headers'   => ['(request-target)', 'Date'],
-        ]);
-
-        $handlerStack = GuzzleHttpSignatures::defaultHandlerFromContext($context);
-        $client = new Client(['handler' => $handlerStack]);
-
-        $headers = [
-            'Accept'       => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
-            'Date'         => date('D, d M Y h:i:s').' GMT',
-            'Content-Type' => 'application/activity+json',
-            'User-Agent'   => 'PixelFedBot - https://pixelfed.org',
-        ];
-
-        $response = $client->post($url, [
-            'options' => [
-                'allow_redirects' => false,
-                'verify'          => true,
-                'timeout'         => 30,
-            ],
-            'headers' => $headers,
-            'body'    => $body,
-        ]);
-
-        return $response->getBody();
-    }
-}

+ 0 - 136
app/Util/ActivityPub/Writer/BaseWriter.php

@@ -1,136 +0,0 @@
-<?php
-
-namespace App\Util\ActivityPub\Writer;
-
-use App\Util\ActivityPub\DiscoverActor;
-
-class BaseWriter {
-
-    protected $context = 'https://www.w3.org/ns/activitystreams';
-    protected $activities = ['Announce','Create','Follow','Like'];
-    protected $audiences = ['public', 'unlisted', 'private', 'direct'];
-    protected $audience = 'public';
-    protected $actors = ['Person'];
-    protected $objects = ['Image','Note'];
-    protected $verb;
-    protected $sourceActivity;
-    protected $activity;
-    protected $profile;
-    protected $to = [];
-    protected $cc = [];
-    protected $bcc = [];
-    protected $response;
-    protected $publishedAt;
-
-    public static function build()
-    {
-        return (new self);
-    }
-
-    public function setContext($context)
-    {
-        $this->context = $context;
-        return $this;
-    }
-
-    public function setActor($profile)
-    {
-        $this->actor = $profile;
-        return $this;
-    }
-
-    public function setActorActivity($activity)
-    {
-        $this->activity = $activity;
-        $this->setPublishedAt($activity->created_at->format('Y-m-d\Th:i:s\Z'));
-        return $this;
-    }
-
-    public function setTo($audience)
-    {
-        $this->to = $audience;
-        return $this;
-    }
-
-    public function setCc($audience)
-    {
-        $this->cc = $audience;
-        return $this;
-    }
-
-    public function setBcc($audience)
-    {
-        $this->bcc = $audience;
-        return $this;
-    }
-
-    public function setPublishedAt($timestamp)
-    {
-        $this->publishedAt = $timestamp;
-        return $this;
-    }
-
-    public function audience($audience)
-    {
-        $this->setAudience($audience);
-        $this->buildAudience();
-        return $this;
-    }
-
-    public function setAudience($audience)
-    {
-        if(in_array($audience, $this->audience)) {
-            $this->audience = $audience;
-        }
-        return $this;
-    }
-
-    public function buildAudience()
-    {
-        switch ($this->audience) {
-          case 'public':
-            $this->to = [
-              $this->context . '#Public'
-            ];
-            $this->cc = [
-              $this->actor->permalink('/followers')
-            ];
-            break;
-
-          case 'unlisted':
-            $this->to = [
-              $this->actor->permalink('/followers')
-            ];
-            $this->cc = [
-              $this->context . '#Public'
-            ];
-            break;
-
-          case 'private':
-            $this->to = [
-              $this->actor->permalink('/followers')
-            ];
-            break;
-          
-          default:
-            # code...
-            break;
-        }
-        return $this;
-    }
-
-    public function get()
-    {
-        return $this->getJson();
-    }
-
-    public function getJson()
-    {
-        return json_encode($this->response);
-    }
-
-    public function getArray()
-    {
-        return $this->response;
-    }
-}

+ 0 - 34
app/Util/HTTPSignatures/Algorithm.php

@@ -1,34 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-abstract class Algorithm
-{
-    /**
-     * @param string $name
-     *
-     * @return HmacAlgorithm
-     *
-     * @throws Exception
-     */
-    public static function create($name)
-    {
-        switch ($name) {
-        case 'hmac-sha1':
-            return new HmacAlgorithm('sha1');
-            break;
-        case 'hmac-sha256':
-            return new HmacAlgorithm('sha256');
-            break;
-        case 'rsa-sha1':
-            return new RsaAlgorithm('sha1');
-            break;
-        case 'rsa-sha256':
-            return new RsaAlgorithm('sha256');
-            break;
-        default:
-            throw new AlgorithmException("No algorithm named '$name'");
-            break;
-        }
-    }
-}

+ 0 - 7
app/Util/HTTPSignatures/AlgorithmException.php

@@ -1,7 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class AlgorithmException extends Exception
-{
-}

+ 0 - 19
app/Util/HTTPSignatures/AlgorithmInterface.php

@@ -1,19 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-interface AlgorithmInterface
-{
-    /**
-     * @return string
-     */
-    public function name();
-
-    /**
-     * @param string $key
-     * @param string $data
-     *
-     * @return string
-     */
-    public function sign($key, $data);
-}

+ 0 - 119
app/Util/HTTPSignatures/Context.php

@@ -1,119 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class Context
-{
-    /** @var array */
-    private $headers;
-
-    /** @var KeyStoreInterface */
-    private $keyStore;
-
-    /** @var array */
-    private $keys;
-
-    /** @var string */
-    private $signingKeyId;
-
-    /** @var AlgorithmInterface */
-    private $algorithm;
-
-    /**
-     * @param array $args
-     *
-     * @throws Exception
-     */
-    public function __construct($args)
-    {
-        if (isset($args['keys']) && isset($args['keyStore'])) {
-            throw new Exception(__CLASS__.' accepts keys or keyStore but not both');
-        } elseif (isset($args['keys'])) {
-            // array of keyId => keySecret
-            $this->keys = $args['keys'];
-        } elseif (isset($args['keyStore'])) {
-            $this->setKeyStore($args['keyStore']);
-        }
-
-        // algorithm for signing; not necessary for verifying.
-        if (isset($args['algorithm'])) {
-            $this->algorithm = Algorithm::create($args['algorithm']);
-        }
-        // headers list for signing; not necessary for verifying.
-        if (isset($args['headers'])) {
-            $this->headers = $args['headers'];
-        }
-
-        // signingKeyId specifies the key used for signing messages.
-        if (isset($args['signingKeyId'])) {
-            $this->signingKeyId = $args['signingKeyId'];
-        } elseif (isset($args['keys']) && 1 === count($args['keys'])) {
-            list($this->signingKeyId) = array_keys($args['keys']); // first key
-        }
-    }
-
-    /**
-     * @return Signer
-     *
-     * @throws Exception
-     */
-    public function signer()
-    {
-        return new Signer(
-            $this->signingKey(),
-            $this->algorithm,
-            $this->headerList()
-        );
-    }
-
-    /**
-     * @return Verifier
-     */
-    public function verifier()
-    {
-        return new Verifier($this->keyStore());
-    }
-
-    /**
-     * @return Key
-     *
-     * @throws Exception
-     * @throws KeyStoreException
-     */
-    private function signingKey()
-    {
-        if (isset($this->signingKeyId)) {
-            return $this->keyStore()->fetch($this->signingKeyId);
-        } else {
-            throw new Exception('no implicit or specified signing key');
-        }
-    }
-
-    /**
-     * @return HeaderList
-     */
-    private function headerList()
-    {
-        return new HeaderList($this->headers);
-    }
-
-    /**
-     * @return KeyStore
-     */
-    private function keyStore()
-    {
-        if (empty($this->keyStore)) {
-            $this->keyStore = new KeyStore($this->keys);
-        }
-
-        return $this->keyStore;
-    }
-
-    /**
-     * @param KeyStoreInterface $keyStore
-     */
-    private function setKeyStore(KeyStoreInterface $keyStore)
-    {
-        $this->keyStore = $keyStore;
-    }
-}

+ 0 - 7
app/Util/HTTPSignatures/Exception.php

@@ -1,7 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class Exception extends \Exception
-{
-}

+ 0 - 41
app/Util/HTTPSignatures/GuzzleHttpSignatures.php

@@ -1,41 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-use GuzzleHttp\HandlerStack;
-use GuzzleHttp\Psr7\Request;
-use App\Util\HttpSignatures\Context;
-
-class GuzzleHttpSignatures
-{
-    /**
-     * @param Context $context
-     * @return HandlerStack
-     */
-    public static function defaultHandlerFromContext(Context $context)
-    {
-        $stack = HandlerStack::create();
-        $stack->push(self::middlewareFromContext($context));
-
-        return $stack;
-    }
-
-    /**
-     * @param Context $context
-     * @return \Closure
-     */
-    public static function middlewareFromContext(Context $context)
-    {
-        return function (callable $handler) use ($context)
-        {
-            return function (
-                Request $request,
-                array $options
-            ) use ($handler, $context)
-            {
-                $request = $context->signer()->sign($request);
-                return $handler($request, $options);
-            };
-        };
-    }
-}

+ 0 - 48
app/Util/HTTPSignatures/HeaderList.php

@@ -1,48 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class HeaderList
-{
-    /** @var array */
-    public $names;
-
-    /**
-     * @param array $names
-     */
-    public function __construct(array $names)
-    {
-        $this->names = array_map(
-            [$this, 'normalize'],
-            $names
-        );
-    }
-
-    /**
-     * @param $string
-     *
-     * @return HeaderList
-     */
-    public static function fromString($string)
-    {
-        return new static(explode(' ', $string));
-    }
-
-    /**
-     * @return string
-     */
-    public function string()
-    {
-        return implode(' ', $this->names);
-    }
-
-    /**
-     * @param $name
-     *
-     * @return string
-     */
-    private function normalize($name)
-    {
-        return strtolower($name);
-    }
-}

+ 0 - 36
app/Util/HTTPSignatures/HmacAlgorithm.php

@@ -1,36 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class HmacAlgorithm implements AlgorithmInterface
-{
-    /** @var string */
-    private $digestName;
-
-    /**
-     * @param string $digestName
-     */
-    public function __construct($digestName)
-    {
-        $this->digestName = $digestName;
-    }
-
-    /**
-     * @return string
-     */
-    public function name()
-    {
-        return sprintf('hmac-%s', $this->digestName);
-    }
-
-    /**
-     * @param string $key
-     * @param string $data
-     *
-     * @return string
-     */
-    public function sign($secret, $data)
-    {
-        return hash_hmac($this->digestName, $data, $secret, true);
-    }
-}

+ 0 - 260
app/Util/HTTPSignatures/Key.php

@@ -1,260 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class Key
-{
-    /** @var string */
-    private $id;
-
-    /** @var string */
-    private $secret;
-
-    /** @var resource */
-    private $certificate;
-
-    /** @var resource */
-    private $publicKey;
-
-    /** @var resource */
-    private $privateKey;
-
-    /** @var string */
-    private $type;
-
-    /**
-     * @param string       $id
-     * @param string|array $secret
-     */
-    public function __construct($id, $item)
-    {
-        $this->id = $id;
-        if (Key::hasX509Certificate($item) || Key::hasPublicKey($item)) {
-            $publicKey = Key::getPublicKey($item);
-        } else {
-            $publicKey = null;
-        }
-        if (Key::hasPrivateKey($item)) {
-            $privateKey = Key::getPrivateKey($item);
-        } else {
-            $privateKey = null;
-        }
-        if (($publicKey || $privateKey)) {
-            $this->type = 'asymmetric';
-            if ($publicKey && $privateKey) {
-                $publicKeyPEM = openssl_pkey_get_details($publicKey)['key'];
-                $privateKeyPublicPEM = openssl_pkey_get_details($privateKey)['key'];
-                if ($privateKeyPublicPEM != $publicKeyPEM) {
-                    throw new KeyException('Supplied Certificate and Key are not related');
-                }
-            }
-            $this->privateKey = $privateKey;
-            $this->publicKey = $publicKey;
-            $this->secret = null;
-        } else {
-            $this->type = 'secret';
-            $this->secret = $item;
-            $this->publicKey = null;
-            $this->privateKey = null;
-        }
-    }
-
-    /**
-     * Retrieves private key resource from a input string or
-     * array of strings.
-     *
-     * @param string|array $object PEM-format Private Key or file path to same
-     *
-     * @return resource|false
-     */
-    public static function getPrivateKey($object)
-    {
-        if (is_array($object)) {
-            foreach ($object as $candidateKey) {
-                $privateKey = Key::getPrivateKey($candidateKey);
-                if ($privateKey) {
-                    return $privateKey;
-                }
-            }
-        } else {
-            // OpenSSL libraries don't have detection methods, so try..catch
-            try {
-                $privateKey = openssl_get_privatekey($object);
-
-                return $privateKey;
-            } catch (\Exception $e) {
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Retrieves public key resource from a input string or
-     * array of strings.
-     *
-     * @param string|array $object PEM-format Public Key or file path to same
-     *
-     * @return resource|false
-     */
-    public static function getPublicKey($object)
-    {
-        if (is_array($object)) {
-            // If we implement key rotation in future, this should add to a collection
-            foreach ($object as $candidateKey) {
-                $publicKey = Key::getPublicKey($candidateKey);
-                if ($publicKey) {
-                    return $publicKey;
-                }
-            }
-        } else {
-            // OpenSSL libraries don't have detection methods, so try..catch
-            try {
-                $publicKey = openssl_get_publickey($object);
-
-                return $publicKey;
-            } catch (\Exception $e) {
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Signing HTTP Messages 'keyId' field.
-     *
-     * @return string
-     *
-     * @throws KeyException
-     */
-    public function getId()
-    {
-        return $this->id;
-    }
-
-    /**
-     * Retrieve Verifying Key - Public Key for Asymmetric/PKI, or shared secret for HMAC.
-     *
-     * @return string Shared Secret or PEM-format Public Key
-     *
-     * @throws KeyException
-     */
-    public function getVerifyingKey()
-    {
-        switch ($this->type) {
-        case 'asymmetric':
-            if ($this->publicKey) {
-                return openssl_pkey_get_details($this->publicKey)['key'];
-            } else {
-                return null;
-            }
-            break;
-        case 'secret':
-            return $this->secret;
-        default:
-            throw new KeyException("Unknown key type $this->type");
-        }
-    }
-
-    /**
-     * Retrieve Signing Key - Private Key for Asymmetric/PKI, or shared secret for HMAC.
-     *
-     * @return string Shared Secret or PEM-format Private Key
-     *
-     * @throws KeyException
-     */
-    public function getSigningKey()
-    {
-        switch ($this->type) {
-        case 'asymmetric':
-            if ($this->privateKey) {
-                openssl_pkey_export($this->privateKey, $pem);
-
-                return $pem;
-            } else {
-                return null;
-            }
-            break;
-        case 'secret':
-            return $this->secret;
-        default:
-            throw new KeyException("Unknown key type $this->type");
-        }
-    }
-
-    /**
-     * @return string 'secret' for HMAC or 'asymmetric'
-     */
-    public function getType()
-    {
-        return $this->type;
-    }
-
-    /**
-     * Test if $object is, points to or contains, X.509 PEM-format certificate.
-     *
-     * @param string|array $object PEM Format X.509 Certificate or file path to one
-     *
-     * @return bool
-     */
-    public static function hasX509Certificate($object)
-    {
-        if (is_array($object)) {
-            foreach ($object as $candidateCertificate) {
-                $result = Key::hasX509Certificate($candidateCertificate);
-                if ($result) {
-                    return $result;
-                }
-            }
-        } else {
-            // OpenSSL libraries don't have detection methods, so try..catch
-            try {
-                openssl_x509_export($object, $null);
-
-                return true;
-            } catch (\Exception $e) {
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Test if $object is, points to or contains, PEM-format Public Key.
-     *
-     * @param string|array $object PEM-format Public Key or file path to one
-     *
-     * @return bool
-     */
-    public static function hasPublicKey($object)
-    {
-        if (is_array($object)) {
-            foreach ($object as $candidatePublicKey) {
-                $result = Key::hasPublicKey($candidatePublicKey);
-                if ($result) {
-                    return $result;
-                }
-            }
-        } else {
-            return false == !openssl_pkey_get_public($object);
-        }
-    }
-
-    /**
-     * Test if $object is, points to or contains, PEM-format Private Key.
-     *
-     * @param string|array $object PEM-format Private Key or file path to one
-     *
-     * @return bool
-     */
-    public static function hasPrivateKey($object)
-    {
-        if (is_array($object)) {
-            foreach ($object as $candidatePrivateKey) {
-                $result = Key::hasPrivateKey($candidatePrivateKey);
-                if ($result) {
-                    return $result;
-                }
-            }
-        } else {
-            return  false != openssl_pkey_get_private($object);
-        }
-    }
-}

+ 0 - 7
app/Util/HTTPSignatures/KeyException.php

@@ -1,7 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class KeyException extends Exception
-{
-}

+ 0 - 36
app/Util/HTTPSignatures/KeyStore.php

@@ -1,36 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class KeyStore implements KeyStoreInterface
-{
-    /** @var Key[] */
-    private $keys;
-
-    /**
-     * @param array $keys
-     */
-    public function __construct($keys)
-    {
-        $this->keys = [];
-        foreach ($keys as $id => $key) {
-            $this->keys[$id] = new Key($id, $key);
-        }
-    }
-
-    /**
-     * @param string $keyId
-     *
-     * @return Key
-     *
-     * @throws KeyStoreException
-     */
-    public function fetch($keyId)
-    {
-        if (isset($this->keys[$keyId])) {
-            return $this->keys[$keyId];
-        } else {
-            throw new KeyStoreException("Key '$keyId' not found");
-        }
-    }
-}

+ 0 - 7
app/Util/HTTPSignatures/KeyStoreException.php

@@ -1,7 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class KeyStoreException extends Exception
-{
-}

+ 0 - 15
app/Util/HTTPSignatures/KeyStoreInterface.php

@@ -1,15 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-interface KeyStoreInterface
-{
-    /**
-     * return the secret for the specified $keyId.
-     *
-     * @param string $keyId
-     *
-     * @return Key
-     */
-    public function fetch($keyId);
-}

+ 0 - 64
app/Util/HTTPSignatures/RsaAlgorithm.php

@@ -1,64 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class RsaAlgorithm implements AlgorithmInterface
-{
-    /** @var string */
-    private $digestName;
-
-    /**
-     * @param string $digestName
-     */
-    public function __construct($digestName)
-    {
-        $this->digestName = $digestName;
-    }
-
-    /**
-     * @return string
-     */
-    public function name()
-    {
-        return sprintf('rsa-%s', $this->digestName);
-    }
-
-    /**
-     * @param string $key
-     * @param string $data
-     *
-     * @return string
-     *
-     * @throws \HttpSignatures\AlgorithmException
-     */
-    public function sign($signingKey, $data)
-    {
-        $algo = $this->getRsaHashAlgo($this->digestName);
-        if (!openssl_get_privatekey($signingKey)) {
-            throw new AlgorithmException("OpenSSL doesn't understand the supplied key (not valid or not found)");
-        }
-        $signature = '';
-        openssl_sign($data, $signature, $signingKey, $algo);
-
-        return $signature;
-    }
-
-    public function verify($message, $signature, $verifyingKey)
-    {
-        $algo = $this->getRsaHashAlgo($this->digestName);
-
-        return openssl_verify($message, base64_decode($signature), $verifyingKey, $algo);
-    }
-
-    private function getRsaHashAlgo($digestName)
-    {
-        switch ($digestName) {
-        case 'sha256':
-            return OPENSSL_ALGO_SHA256;
-        case 'sha1':
-            return OPENSSL_ALGO_SHA1;
-        default:
-            throw new HttpSignatures\AlgorithmException($digestName.' is not a supported hash format');
-      }
-    }
-}

+ 0 - 38
app/Util/HTTPSignatures/Signature.php

@@ -1,38 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-use Psr\Http\Message\RequestInterface;
-
-class Signature
-{
-    /** @var Key */
-    private $key;
-
-    /** @var AlgorithmInterface */
-    private $algorithm;
-
-    /** @var SigningString */
-    private $signingString;
-
-    /**
-     * @param RequestInterface   $message
-     * @param Key                $key
-     * @param AlgorithmInterface $algorithm
-     * @param HeaderList         $headerList
-     */
-    public function __construct($message, Key $key, AlgorithmInterface $algorithm, HeaderList $headerList)
-    {
-        $this->key = $key;
-        $this->algorithm = $algorithm;
-        $this->signingString = new SigningString($headerList, $message);
-    }
-
-    public function string()
-    {
-        return $this->algorithm->sign(
-            $this->key->getSigningKey(),
-            $this->signingString->string()
-          );
-    }
-}

+ 0 - 49
app/Util/HTTPSignatures/SignatureParameters.php

@@ -1,49 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class SignatureParameters
-{
-    /**
-     * @param Key                $key
-     * @param AlgorithmInterface $algorithm
-     * @param HeaderList         $headerList
-     * @param Signature          $signature
-     */
-    public function __construct($key, $algorithm, $headerList, $signature)
-    {
-        $this->key = $key;
-        $this->algorithm = $algorithm;
-        $this->headerList = $headerList;
-        $this->signature = $signature;
-    }
-
-    /**
-     * @return string
-     */
-    public function string()
-    {
-        return implode(',', $this->parameterComponents());
-    }
-
-    /**
-     * @return array
-     */
-    private function parameterComponents()
-    {
-        return [
-            sprintf('keyId="%s"', $this->key->getId()),
-            sprintf('algorithm="%s"', $this->algorithm->name()),
-            sprintf('headers="%s"', $this->headerList->string()),
-            sprintf('signature="%s"', $this->signatureBase64()),
-        ];
-    }
-
-    /**
-     * @return string
-     */
-    private function signatureBase64()
-    {
-        return base64_encode($this->signature->string());
-    }
-}

+ 0 - 111
app/Util/HTTPSignatures/SignatureParametersParser.php

@@ -1,111 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class SignatureParametersParser
-{
-    /** @var string */
-    private $input;
-
-    /**
-     * @param string $input
-     */
-    public function __construct($input)
-    {
-        $this->input = $input;
-    }
-
-    /**
-     * @return array
-     */
-    public function parse()
-    {
-        $result = $this->pairsToAssociative(
-            $this->arrayOfPairs()
-        );
-        $this->validate($result);
-
-        return $result;
-    }
-
-    /**
-     * @param array $pairs
-     *
-     * @return array
-     */
-    private function pairsToAssociative($pairs)
-    {
-        $result = [];
-        foreach ($pairs as $pair) {
-            $result[$pair[0]] = $pair[1];
-        }
-
-        return $result;
-    }
-
-    /**
-     * @return array
-     */
-    private function arrayOfPairs()
-    {
-        return array_map(
-            [$this, 'pair'],
-            $this->segments()
-        );
-    }
-
-    /**
-     * @return array
-     */
-    private function segments()
-    {
-        return explode(',', $this->input);
-    }
-
-    /**
-     * @param $segment
-     *
-     * @return array
-     *
-     * @throws SignatureParseException
-     */
-    private function pair($segment)
-    {
-        $segmentPattern = '/\A(keyId|algorithm|headers|signature)="(.*)"\z/';
-        $matches = [];
-        $result = preg_match($segmentPattern, $segment, $matches);
-        if (1 !== $result) {
-            throw new SignatureParseException("Signature parameters segment '$segment' invalid");
-        }
-        array_shift($matches);
-
-        return $matches;
-    }
-
-    /**
-     * @param $result
-     *
-     * @throws SignatureParseException
-     */
-    private function validate($result)
-    {
-        $this->validateAllKeysArePresent($result);
-    }
-
-    /**
-     * @param $result
-     *
-     * @throws SignatureParseException
-     */
-    private function validateAllKeysArePresent($result)
-    {
-        // Regexp in pair() ensures no unwanted keys exist.
-        // Ensure that all wanted keys exist.
-        $wanted = ['keyId', 'algorithm', 'headers', 'signature'];
-        $missing = array_diff($wanted, array_keys($result));
-        if (!empty($missing)) {
-            $csv = implode(', ', $missing);
-            throw new SignatureParseException("Missing keys $csv");
-        }
-    }
-}

+ 0 - 7
app/Util/HTTPSignatures/SignatureParseException.php

@@ -1,7 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class SignatureParseException extends Exception
-{
-}

+ 0 - 7
app/Util/HTTPSignatures/SignedHeaderNotPresentException.php

@@ -1,7 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-class SignedHeaderNotPresentException extends Exception
-{
-}

+ 0 - 104
app/Util/HTTPSignatures/Signer.php

@@ -1,104 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-use Psr\Http\Message\RequestInterface;
-
-class Signer
-{
-    /** @var Key */
-    private $key;
-
-    /** @var HmacAlgorithm */
-    private $algorithm;
-
-    /** @var HeaderList */
-    private $headerList;
-
-    /**
-     * @param Key           $key
-     * @param HmacAlgorithm $algorithm
-     * @param HeaderList    $headerList
-     */
-    public function __construct($key, $algorithm, $headerList)
-    {
-        $this->key = $key;
-        $this->algorithm = $algorithm;
-        $this->headerList = $headerList;
-    }
-
-    /**
-     * @param RequestInterface $message
-     *
-     * @return RequestInterface
-     */
-    public function sign($message)
-    {
-        $signatureParameters = $this->signatureParameters($message);
-        $message = $message->withAddedHeader('Signature', $signatureParameters->string());
-        $message = $message->withAddedHeader('Authorization', 'Signature '.$signatureParameters->string());
-
-        return $message;
-    }
-
-    /**
-     * @param RequestInterface $message
-     *
-     * @return RequestInterface
-     */
-    public function signWithDigest($message)
-    {
-        $message = $this->addDigest($message);
-
-        return $this->sign($message);
-    }
-
-    /**
-     * @param RequestInterface $message
-     *
-     * @return RequestInterface
-     */
-    private function addDigest($message)
-    {
-        if (!array_search('digest', $this->headerList->names)) {
-            $this->headerList->names[] = 'digest';
-        }
-        $message = $message->withoutHeader('Digest')
-            ->withHeader(
-                'Digest',
-                'SHA-256='.base64_encode(hash('sha256', $message->getBody(), true))
-            );
-
-        return $message;
-    }
-
-    /**
-     * @param RequestInterface $message
-     *
-     * @return SignatureParameters
-     */
-    private function signatureParameters($message)
-    {
-        return new SignatureParameters(
-            $this->key,
-            $this->algorithm,
-            $this->headerList,
-            $this->signature($message)
-        );
-    }
-
-    /**
-     * @param RequestInterface $message
-     *
-     * @return Signature
-     */
-    private function signature($message)
-    {
-        return new Signature(
-            $message,
-            $this->key,
-            $this->algorithm,
-            $this->headerList
-        );
-    }
-}

+ 0 - 89
app/Util/HTTPSignatures/SigningString.php

@@ -1,89 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-use Psr\Http\Message\RequestInterface;
-
-class SigningString
-{
-    /** @var HeaderList */
-    private $headerList;
-
-    /** @var RequestInterface */
-    private $message;
-
-    /**
-     * @param HeaderList       $headerList
-     * @param RequestInterface $message
-     */
-    public function __construct(HeaderList $headerList, $message)
-    {
-        $this->headerList = $headerList;
-        $this->message = $message;
-    }
-
-    /**
-     * @return string
-     */
-    public function string()
-    {
-        return implode("\n", $this->lines());
-    }
-
-    /**
-     * @return array
-     */
-    private function lines()
-    {
-        return array_map(
-            [$this, 'line'],
-            $this->headerList->names
-        );
-    }
-
-    /**
-     * @param string $name
-     *
-     * @return string
-     *
-     * @throws SignedHeaderNotPresentException
-     */
-    private function line($name)
-    {
-        if ('(request-target)' == $name) {
-            return $this->requestTargetLine();
-        } else {
-            return sprintf('%s: %s', $name, $this->headerValue($name));
-        }
-    }
-
-    /**
-     * @param string $name
-     *
-     * @return string
-     *
-     * @throws SignedHeaderNotPresentException
-     */
-    private function headerValue($name)
-    {
-        if ($this->message->hasHeader($name)) {
-            $header = $this->message->getHeader($name);
-
-            return end($header);
-        } else {
-            throw new SignedHeaderNotPresentException("Header '$name' not in message");
-        }
-    }
-
-    /**
-     * @return string
-     */
-    private function requestTargetLine()
-    {
-        return sprintf(
-            '(request-target): %s %s',
-            strtolower($this->message->getMethod()),
-            $this->message->getRequestTarget()
-        );
-    }
-}

+ 0 - 202
app/Util/HTTPSignatures/Verification.php

@@ -1,202 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-use Psr\Http\Message\RequestInterface;
-
-class Verification
-{
-    /** @var RequestInterface */
-    private $message;
-
-    /** @var KeyStoreInterface */
-    private $keyStore;
-
-    /** @var array */
-    private $_parameters;
-
-    /**
-     * @param RequestInterface  $message
-     * @param KeyStoreInterface $keyStore
-     */
-    public function __construct($message, KeyStoreInterface $keyStore)
-    {
-        $this->message = $message;
-        $this->keyStore = $keyStore;
-    }
-
-    /**
-     * @return bool
-     */
-    public function isValid()
-    {
-        return $this->hasSignatureHeader() && $this->signatureMatches();
-    }
-
-    /**
-     * @return bool
-     */
-    private function signatureMatches()
-    {
-        try {
-            $key = $this->key();
-            switch ($key->getType()) {
-                case 'secret':
-                  $random = random_bytes(32);
-                  $expectedResult = hash_hmac(
-                      'sha256', $this->expectedSignatureBase64(),
-                      $random,
-                      true
-                  );
-                  $providedResult = hash_hmac(
-                      'sha256', $this->providedSignatureBase64(),
-                      $random,
-                      true
-                  );
-
-                  return $expectedResult === $providedResult;
-                case 'asymmetric':
-                    $signedString = new SigningString(
-                        $this->headerList(),
-                        $this->message
-                    );
-                    $hashAlgo = explode('-', $this->parameter('algorithm'))[1];
-                    $algorithm = new RsaAlgorithm($hashAlgo);
-                    $result = $algorithm->verify(
-                        $signedString->string(),
-                        $this->parameter('signature'),
-                        $key->getVerifyingKey());
-
-                    return $result;
-                default:
-                    throw new Exception("Unknown key type '".$key->getType()."', cannot verify");
-            }
-        } catch (SignatureParseException $e) {
-            return false;
-        } catch (KeyStoreException $e) {
-            return false;
-        } catch (SignedHeaderNotPresentException $e) {
-            return false;
-        }
-    }
-
-    /**
-     * @return string
-     */
-    private function expectedSignatureBase64()
-    {
-        return base64_encode($this->expectedSignature()->string());
-    }
-
-    /**
-     * @return Signature
-     */
-    private function expectedSignature()
-    {
-        return new Signature(
-            $this->message,
-            $this->key(),
-            $this->algorithm(),
-            $this->headerList()
-        );
-    }
-
-    /**
-     * @return string
-     */
-    private function providedSignatureBase64()
-    {
-        return $this->parameter('signature');
-    }
-
-    /**
-     * @return Key
-     */
-    private function key()
-    {
-        return $this->keyStore->fetch($this->parameter('keyId'));
-    }
-
-    /**
-     * @return HmacAlgorithm
-     */
-    private function algorithm()
-    {
-        return Algorithm::create($this->parameter('algorithm'));
-    }
-
-    /**
-     * @return HeaderList
-     */
-    private function headerList()
-    {
-        return HeaderList::fromString($this->parameter('headers'));
-    }
-
-    /**
-     * @param string $name
-     *
-     * @return string
-     *
-     * @throws Exception
-     */
-    private function parameter($name)
-    {
-        $parameters = $this->parameters();
-        if (!isset($parameters[$name])) {
-            throw new Exception("Signature parameters does not contain '$name'");
-        }
-
-        return $parameters[$name];
-    }
-
-    /**
-     * @return array
-     */
-    private function parameters()
-    {
-        if (!isset($this->_parameters)) {
-            $parser = new SignatureParametersParser($this->signatureHeader());
-            $this->_parameters = $parser->parse();
-        }
-
-        return $this->_parameters;
-    }
-
-    /**
-     * @return bool
-     */
-    private function hasSignatureHeader()
-    {
-        return $this->message->hasHeader('Signature') || $this->message->hasHeader('Authorization');
-    }
-
-    /**
-     * @return string
-     *
-     * @throws Exception
-     */
-    private function signatureHeader()
-    {
-        if ($signature = $this->fetchHeader('Signature')) {
-            return $signature;
-        } elseif ($authorization = $this->fetchHeader('Authorization')) {
-            return substr($authorization, strlen('Signature '));
-        } else {
-            throw new Exception('HTTP message has no Signature or Authorization header');
-        }
-    }
-
-    /**
-     * @param $name
-     *
-     * @return string|null
-     */
-    private function fetchHeader($name)
-    {
-        // grab the most recently set header.
-        $header = $this->message->getHeader($name);
-
-        return end($header);
-    }
-}

+ 0 - 31
app/Util/HTTPSignatures/Verifier.php

@@ -1,31 +0,0 @@
-<?php
-
-namespace App\Util\HttpSignatures;
-
-use Psr\Http\Message\RequestInterface;
-
-class Verifier
-{
-    /** @var KeyStoreInterface */
-    private $keyStore;
-
-    /**
-     * @param KeyStoreInterface $keyStore
-     */
-    public function __construct(KeyStoreInterface $keyStore)
-    {
-        $this->keyStore = $keyStore;
-    }
-
-    /**
-     * @param RequestInterface $message
-     *
-     * @return bool
-     */
-    public function isValid($message)
-    {
-        $verification = new Verification($message, $this->keyStore);
-
-        return $verification->isValid();
-    }
-}

+ 18 - 1
resources/views/settings/home.blade.php

@@ -12,7 +12,9 @@
     </div>
     <div class="col-sm-9">
       <p class="lead font-weight-bold mb-0">{{Auth::user()->username}}</p>
-      <p><a href="#" class="font-weight-bold change-profile-photo" data-toggle="collapse" data-target="#avatarCollapse" aria-expanded="false" aria-controls="avatarCollapse">Change Profile Photo</a></p>
+      <p class="">
+        <a href="#" class="font-weight-bold change-profile-photo" data-toggle="collapse" data-target="#avatarCollapse" aria-expanded="false" aria-controls="avatarCollapse">Change Profile Photo</a>
+      </p>
       <div class="collapse" id="avatarCollapse">
         <form method="post" action="/settings/avatar" enctype="multipart/form-data">
         @csrf
@@ -27,6 +29,9 @@
         </div>
         </form>
       </div>
+      <p class="">
+        <a class="font-weight-bold text-muted delete-profile-photo" href="#">Delete Profile Photo</a>
+      </p>
     </div>
   </div>
   <form method="post">
@@ -144,5 +149,17 @@
           reader.readAsDataURL(file);
       }
   });
+
+  $('.delete-profile-photo').on('click', function(e) {
+    e.preventDefault();
+    if(window.confirm('Are you sure you want to delete your profile photo.') == false) {
+      return;
+    }
+    axios.delete('/settings/avatar').then(res => {
+      window.location.href = window.location.href;
+    }).catch(err => {
+      swal('Error', 'An error occured, please try again later', 'error');
+    });
+  });
 </script>
 @endpush

+ 1 - 0
routes/web.php

@@ -164,6 +164,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
         Route::post('home', 'SettingsController@homeUpdate');
         Route::get('avatar', 'SettingsController@avatar')->name('settings.avatar');
         Route::post('avatar', 'AvatarController@store');
+        Route::delete('avatar', 'AvatarController@deleteAvatar');
         Route::get('password', 'SettingsController@password')->name('settings.password')->middleware('dangerzone');
         Route::post('password', 'SettingsController@passwordUpdate')->middleware('dangerzone');
         Route::get('email', 'SettingsController@email')->name('settings.email');

TEMPAT SAMPAH
storage/app/public/avatars/default.png