silverstripe / silverstripe-s3

Silverstripe module to store assets in S3 rather than on the local filesystem (SS4/SS5 only)
BSD 3-Clause "New" or "Revised" License
20 stars 25 forks source link

No preview on upload #33

Closed jamieduck closed 3 years ago

jamieduck commented 4 years ago

In Silverstripe 4.4.4 when you upload a file, it does not show the preview of the file unless you publish the file.

It puts the image in protected and returns a 403 forbidden error when it should let you see the file preview so you know what file you are editing.

jamieduck commented 4 years ago

it says this on the preview box:

The request signature we calculated does not match the signature you provided. Check your key and signing method.

But on the focus point it shows.

obj63mc commented 4 years ago

This appears to only be happening in the Asset Admin - https://github.com/silverstripe/silverstripe-asset-admin

So not sure what would be causing this as if you try it on say an UploadField on a page or object it works just fine. Will see what we can find out though but guessing it is some post processing or thumbnail generation issue with asset admin

obj63mc commented 4 years ago

Okay so I think I know what the issue is, as to how to fix it not sure. It is definitely related to the components of asset admin/ cms admin and the form fields (react rendering) which is causing the issue.

When looking at our code - we simply use the S3 client to generate the url. This is then returning the following in the graphql -

Screen Shot 2019-10-23 at 10 49 59 AM

Example url returned - is a signed url

In the cms on the preview, and image tags you will see that it is appending ?vid={theversion} on to the end of the signed url. That appended text is then breaking the link. If you remove that from the ?vid=... from the end of the signed url via dev tools you will see that the image loads just fine. Due to this being more of an issue with the react components and not this we will need to open a new issue in the appropriate repos. Will see if I can track those down and open an issue there.

obj63mc commented 4 years ago

@jamieduck - a workaround that you can implement till the issue with asset-admin is resolved -

  1. Create a JS file with the following code and place it in your public folder - this is a simple mutation observer that looks for images and thumbnail previews being added to the dom as well as looking for any on initial load and removes the ?vid=X for the image url.

    (function(window) {
        var listeners = [],
        doc = window.document,
        MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
        observer;
    
        function domready(selector, fn) {
            // Store the selector and callback to be monitored
            listeners.push({
                selector: selector,
                fn: fn
            });
            if (!observer) {
                // Watch for changes in the document
                observer = new MutationObserver(check);
                observer.observe(doc.documentElement, {
                    childList: true,
                    subtree: true
                });
            }
            // Check if the element is currently in the DOM
            check();
        }
    
        function check() {
            // Check the DOM for elements matching a stored selector
            for (var i = 0, len = listeners.length, listener, elements; i < len; i++) {
                listener = listeners[i];
                // Query for elements matching the specified selector
                elements = doc.querySelectorAll(listener.selector);
                for (var j = 0, jLen = elements.length, element; j < jLen; j++) {
                    element = elements[j];
                    // Make sure the callback isn't invoked with the
                    // same element more than once
                    if (!element.ready) {
                        element.ready = true;
                        // Invoke the callback with the element
                        listener.fn.call(element, element);
                    }
                }
            }
        }
    
        var regex = /(\?vid=[0-9]+)/g;
    
        //checkForAWS and vid
        function checkForAWS(el){
            if(el.src && el.src.indexOf('AWS4') !== false){
                el.src = el.src.replace(regex, '');
            } else if(el.style && el.style.backgroundImage && el.style.backgroundImage.indexOf('AWS') !== false){
                el.style.backgroundImage = el.style.backgroundImage.replace(regex, '');
            }
        }
        domready('img', function(el) {
            checkForAWS(el);
        });
    
        domready('.gallery-item__thumbnail', function(el) {
            checkForAWS(el);
        });
    
        var images = document.querySelectorAll('img');
        for(var i = 0; i < images.length; i++){
            checkForAWS(images[i]);
        }
    
        var thumbnails = document.querySelectorAll('.gallery-item__thumbnail');
        for(var i = 0; i < thumbnails.length; i++){
            checkForAWS(thumbnails[i]);
        }
    })(window);
  2. Once that is saved into your public folder (example /public/awsimagecheck.js) you then just need to have LeftAndMain include this new custom js - add the following to your projects YML config -

    SilverStripe\Admin\LeftAndMain:
    extra_requirements_javascript:
        - awsimagecheck.js

Hopefully this can help in the mean time.

jamieduck commented 4 years ago

@obj63mc

Thank you so much this has helped a lot. Thanks

zanderwar commented 4 years ago

Related to #39 however in that issue the opposite is occurring when usings SilverStripe API to add the file.

The image/thumbnail is visible while unpublished/protected but not visible when published/public.

The solution above only fixes images that are directly uploaded to the Asset Manager (thanks)

obj63mc commented 3 years ago

This should be resolved now with the latest updates to #43

leochenftw commented 3 years ago

just a minor change to the regex:

var regex = /((\&|\?)vid=[0-9]+)/g;

Now you can have the preview on the asset detail sidebar when you select a file.