mattmilburn/strapi-plugin-preview-button

Ability to generate url (or parts of it) when the button is clicked

marcsello opened this issue · 2 comments

Currently urls for posts are pre-generated. By allowing the generation of the url (or parts of it) it would be possible to create more secure preview urls. The static key solution suggested in the docs is problematic for larger deployments, once the key leaked it have to be rotated, and rotation requires the Strapi instance to be restarted. This not only painful to manage, but it is impossible to track when the key is leaked so it have to be rotated on a timely basis. Generating tokens on demand would be a lot more secure, because you could use time based algorithms (JWT for example).

This would also open up other possibilities, for having custom logic determining the preview url.

I'm thinking for something similar:

      // ...
      'preview-button': {
        config: {
          contentTypes: [
            {
              uid: 'api::post.post',
              draft: {
                url: 'https://my-preview-solution.tld/{slug}',
                query: {
                  token: function() {
                    return generateToken();
                  }
                },
              },
            },
          ],
        },
      },
      // ...

The button's onClick handler could check if the provided url is callable. If yes, it should call it and use the return value as the url. (Promises or something similar would be even better).

I'm not very familiar JavaScript so please forgive me for my inaccuracies.

Hi @marcsello I think adding more callable options into the configuration may make its way into a future release.

I understand the desire for total security here but so far I cannot find a way to achieve that with this plugin. The reason is because no matter how you hide your secret key or token values, when the user clicks the preview button they will be redirected to a URL which has all of those values included. If that user wanted to copy the sensitive values from the URL, there is little standing in their way.

Ideally, if you are including a secret key then you want to use a preview URL that interprets the query string params, validates the secret key, and once again redirects to the preview page without the sensitive data in the URL. This would still not stop someone from finding the secret key if they wanted it, but it doesn't leave it sitting in front of the them either.

I think if this were to be made truly secure, there would need to be more infrastructure involved to work behind the scenes and validate things but unfortunately I cannot achieve that with this plugin right now.

The reason is because no matter how you hide your secret key or token values, when the user clicks the preview button they will be redirected to a URL which has all of those values included. If that user wanted to copy the sensitive values from the URL, there is little standing in their way.

The key here is that the key is time based. That's why It would be nice if it could be generated just when the user clicks the button. The secret that would be applied to the query string would be valid only for let's say 5 minutes. Obviously this does not give total protection, but I'm just trying to implement a protection when our authors pass links around, so if the secret gets accidentally leaked, it wouldn't be useful after a while.

Another advantage of generating links with custom fields just when the user presses the button would be the ability to generate keys that allow access only to the specific resource the user want to preview. This way an accidentally leaked secret wouldn't allow a third party to view everything.

Both of these would be achieved with something simple, like a JWT token, but without this feature none of those would be possible. It is also a requirement for those, that the custom URL generation happens on server side.