Blog

I write on blua.blue, dev.to and groups.hyvor.com

dev.to plugin for headless CMS blua.blue (part 2)

Recap

As elaborated in the article "Cross publishing to dev.to" (on dev.to || on blua.blue), I created a plugin for blua.blue that cross posts to dev.to by utilizing the webhook functionality of blua.blue. I did this as a proof of concept of how to build custom plugins for blua.blue in general.

While the general approach was proven, I had outstanding problems to tackle, while allowing for the folowing rules:

- modifications to blua.blue's models & functionality are out of the question to stay future proof

- saving credentials as plain-text in the MySQL database is not an option

- somehow prohibit public access while not having a JWT from the user present in the webhooks

Outstanding problems

So, what where the remaining issues? Well, first of all, having the API key as server-side credentials only enabled one dev.to user-account. That is a big problem considering that a multi-user system should enable anyone with a user account to post as individual author using an individual user account. Letting people publish in my name was certainly not an option. Blua.blue has the ability to set tokens that are transmitted with the webhooks as bearer tokens. However, these tokens are stored in plain text and are intended to provide identification of the origin of a call, not to securely store credentials. So what to do?

The principle

So here is the solution I came up with: I would create an endpoint as a route for setup purposes. There you can input your API-key and send it to the plugin where a instance-specific encryption-key ( outside the public web-root via `neoan3 credentials`  ) would encrypt and serialize it.

In a second step, the result of this operation is then provided as token to the webhook pointing at the plugin and stored in the database. 

Whenever the plugin receives a call it can now revert this operation ( deserialize & decrypt ) and use the result (the plain API-key) for communication with dev.to, at which point the dev.to API will either recognize the user and authentication or not.

Since the POST-endpoint is used by the webhook and I wanted to contain the plugin to one component, I used this GET function:

function getDevTo(array $body = [])
    {
        // make sure only logged in users can execute this
        Stateless::restrict();
        $answer = [];
        if (isset($body['apiKey'])) {
            // assign
            $this->apiKey = $body['apiKey'];
            // use existing header construction
            $header = $this->curlHeader();
            // make a test-call with given API key to provide feedback for the frontend
            $testAnswer = Curl::curling('https://dev.to/api/articles/me',[],$header, 'GET');
            // obtain neoan3 credentials
            $credentials = getCredentials();
            $key = $credentials['blua_devto']['salt'];
            // encrypt & serialize
            $encrypted = Ops::serialize(Ops::encrypt($body['apiKey'], $key));
            $answer = ['token' => $encrypted, 'test' => $testAnswer];
        }

        return $answer;
    }

In order to retrieve the API key, I had to make changes to the POST function as well:

function postDevTo(array $body)
    {
        try {
            $credentials = getCredentials();
            // check token
            if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
                return ['webhook' => 'denied'];
            }

            $this->apiKey = $this->getApiKey($credentials, substr($_SERVER['HTTP_AUTHORIZATION'], 7));


            switch ($body['event']) {
                case 'created':
                case 'updated':
                    // find existing
                    $update = $this->investigateStoreObject($body['payload']['store']);
                    $devBody = $this->transformPayload($body['payload']);
                    $this->sendToDevTo($devBody, $update);
                    break;
                case 'deleted':
                    break;
            }
        } catch (\Exception $e) {
            throw new RouteException('Unable to execute dev.to plugin', 500);
        }
        return ['webhook' => 'received'];
    }

I uploaded the changes to blua.blue and here I am using it!

GitHub: https://github.com/blua-blue/devTo

Want to try it out?

Sign up at https://blua.blue and then visit https://blua.blue/dev-to for the setup.

image

What is composer?

Composer has become PHP's package & dependency manager. Why you should use it.

image

MySQL: ERROR1364 fix

The painful realization of why people use containers.

image

Cyber wars: Defending your server

Maintaining your own server can be a thrill. High security standards can protect you from data leakage, injection attacks and DDoS attempts. But what about adaptive brute force?

Git: globally change GitHub-remotes from git@ to https

Does your IDE or composer set remote repositories to ssh rather than https? Or are repositories you are using set up that way? You are not alone. Let's fix it once and for all!

VueJS & neoan3: a love story.

Setting up neoan3 to play nice with Vue isn't hard. Here is how the two frameworks are combined to support fast, dynamic and rapid development.

image

MySQL in PHP - how to deal with databases

How I handle MYSQL database transactions in PHP

Install PHP 7.4 on Ubuntu

Finally PHP 7.4 is out! You have read about the new features, you have followed externals, you have gathered ideas on how new capabilities will save time. Let's get it running.

How to install global npm packages without sudo on Ubuntu

Running npm on a server can be painful. Privileges are there for a reason, and so is sudo. Running npm with sudo is not the solution.

image

Static content pages - still the fastest web-experience

Tutorial: How to utilize blua.blue to generate static content for your website.

image

blua.blue PHP SDK

Create your own blog.

image

dev.to plugin for headless CMS blua.blue (part 2)

A solution to supplying plugins to blua.blue

image

Cross publishing to dev.to

How to publish your content to dev.to from blua.blue - hopefully

Transformer - falling in love with PHP's magic methods all over again

PHP's magic functions have been around for a long time. But there were always good reasons to avoid them. Transformer is a practical and reliable way to make use of the most common operations we program: CRUD operations.

The Uselessness of Pre-Assessment

After almost two decades in the industry, new jobs will still ask you for "assessment tests". A little rant...

image

SEO strategies for blua.blue

How to get your content listed where you want it to.

image

How to Build an Express App in Node That Reads From a Headless CMS

A headless CMS lets you design your own front-end, sometimes your own back-end. Let's set up a small application to get us started. Beginner friendly. Approx. 20 min. to reproduce / follow along

image

Help us document neoan3

Over 4000 brave developers are exploring the framework on their own.

image

When politics kill innovation

How misunderstood diversity killed the PHP Central Europe Conference for good.