Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1 from Flowframe/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
Larsklopstra committed Jun 19, 2021
2 parents c83068b + 5495b3d commit 2ba4ace
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 31 deletions.
31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,21 @@ Once you have setup up the server you can start using the client side package.
First, setup your `.env`:

```
OG_IMAGE_URL=<your_server_url>
OG_IMAGE_URL=<your_server_url> // https://your-app-on.vercel.com/api
OG_IMAGE_TEMPLATE_PATH=<your_template_path> // default _og-image, we recommend to keep this
OG_IMAGE_SECRET_TOKEN=<your_secret_token_from_server>
```

_Don't forget to add the /api suffix._

And then generate your image:

```php
// helper function, you can also use the Facade: `OgImageClient::create(...)`
og([
'template' => '_og-images/example' // resources/views/_og-images/example.blade.php
// helper function, you can also use the Facade: `OgImageClient::generate(...)`
$image = og()->generate([
'template' => '_og-images/example', // resources/views/_og-images/example.blade.php

// Attributes which will be used in the template view
'title' => 'Hello Flowframe',
Expand All @@ -50,10 +54,27 @@ og([
'Wow',
'Much',
'Cool',
];
],
]);
```

When developing locally you can also preview your image by doing:

```php
return og()->preview([
'template' => '_og-images/example',
'title' => 'Hello Flowframe',
'subtitle' => 'How are you doing?',
'options' => [
'Wow',
'Much',
'Cool',
],
]);
```

This will render the template with data.

### Templates

The templates get served from the website itself. Alternatively, you can override the url inside the payload to point to another site.
Expand Down
2 changes: 2 additions & 0 deletions config/og-image-client.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
return [
'url' => env('OG_IMAGE_URL'),

'template_path' => env('OG_IMAGE_TEMPLATE_PATH', '_og-image'),

'secret_token' => env('OG_IMAGE_SECRET_TOKEN'),
];
4 changes: 2 additions & 2 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

abort_unless($signature, 400, 'Missing signature.');

$decodedPayload = OgImageClient::decodePayload($payload);
$signatureIsValid = OgImageClient::verifySignature($decodedPayload, $signature);
$decodedPayload = OgImageClient::decode($payload);
$signatureIsValid = OgImageClient::verifyIntegrity($payload, $signature);

abort_unless($signatureIsValid, 400, 'Invalid signature.');

Expand Down
10 changes: 8 additions & 2 deletions src/Facades/OgImageClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@
/**
* @see \Flowframe\OgImageClient\OgImageClient
*
* @method static string create(array $payload)
* @method static array decodePayload(array $payload)
* @method static string generate(array $payload)
* @method static preview(array $payload)
* @method static array decode(string $payload)
* @method static bool verifyIntegrity(string $payload, string $signature)
* @method static void validate(array $payload)
* @method static string buildQuery(array $payload)
* @method static string sign(sign $payload)
* @method static string encode(array $payload)
*/
class OgImageClient extends Facade
{
Expand Down
52 changes: 34 additions & 18 deletions src/OgImageClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,63 @@

class OgImageClient
{
public function create(array $payload): string
public function generate(array $payload): string
{
throw_unless($payload['template'], 'A template is required.');
$this->validate($payload);

throw_unless(config('og-image-client.url'), '`url` missing in og-image-client configuration.');
$payload['url'] = isset($payload['url']) ? $payload['url'] : url(config('og-image-client.template_path'));

throw_unless(config('og-image-client.secret_token'), '`secret_token` missing in og-image-client configuration.');
return $this->buildQuery($payload);
}

throw_unless(isset($payload['template']), 'A template is required in your payload.');
public function preview(array $payload)
{
$this->validate($payload);

$payload['url'] = isset($payload['url']) ? $payload['url'] : url('_og-image');
return view($payload['template'], [
'payload' => $payload,
]);
}

return $this->createUrl($payload);
public function decode(string $payload): array
{
return json_decode(base64_decode($payload), true);
}

private function encodePayload(array $payload): string
public function verifyIntegrity(string $payload, string $signature): bool
{
return urlencode(json_encode($payload));
return $this->sign($payload) === $signature;
}

public function decodePayload(string $payload): array
public function validate(array $payload): void
{
return json_decode(urldecode($payload), true);
throw_unless($payload['template'], 'A template is required.');

throw_unless(config('og-image-client.url'), '`url` missing in og-image-client configuration.');

throw_unless(config('og-image-client.secret_token'), '`secret_token` missing in og-image-client configuration.');

throw_unless(isset($payload['template']), 'A template is required in your payload.');

throw_unless(view()->exists($payload['template']), "View for template `{$payload['template']}` doesn't exist.");
}

private function createUrl(array $payload): string
public function buildQuery(array $payload): string
{
$encodedPayload = $this->encodePayload($payload);
$signature = $this->signPayload($payload);
$encodedPayload = $this->encode($payload);
$signature = $this->sign($encodedPayload);
$url = config('og-image-client.url');

return "{$url}?payload={$encodedPayload}&signature={$signature}";
}

private function signPayload(array $payload): string
public function sign(string $payload): string
{
return hash_hmac('sha256', json_encode($payload), config('og-image-client.secret_token'));
return hash_hmac('sha256', $payload, config('og-image-client.secret_token'));
}

public function verifySignature(array $payload, string $signature): bool
public function encode(array $payload): string
{
return $this->signPayload($payload) === $signature;
return base64_encode(json_encode($payload));
}
}
8 changes: 4 additions & 4 deletions src/helpers.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<?php

use Flowframe\OgImageClient\Facades\OgImageClient;
use Flowframe\OgImageClient\OgImageClient;

if (! function_exists('og')) {
function og(array $payload): string
function og(): OgImageClient
{
return OgImageClient::create($payload);
return app(OgImageClient::class);
}
}

// Just because it's cool
if (! function_exists('📸')) {
function 📸(array $payload): string
{
return OgImageClient::create($payload);
return og()->generate($payload);
}
}

0 comments on commit 2ba4ace

Please sign in to comment.