How to force browser to download public asset from GCP Storage Bucket url? - node.js

I have assets from Wordpress being uploaded to GCP Storage bucket. But when I then list all these links to these assets within the website im working on, I would like the user to automatically download the file instead of viewing it in the browser when the user clicks on the link.
Is there an "easy" way to implement this behaviour?
The project is running with Wordpress as headless API, and Next.js frontend.
Thanks

You can change object metadata for your objects in Cloud Storage to force browsers to download files directly, instead of previewing them. You can do this through the available content-disposition property. Setting this property to attachment will allow you to directly download the content.
I quickly tested downloading public objects with and without this property and can confirm the behavior, downloads do happen directly. The documentation explains how to quickly change the metadata for existing objects in your bucket. While it is not directly mentioned, you can use wildcards to apply metadata changes to multiple objects at the same time. For example this command will apply the content-disposition property in all objects of the bucket:
gsutil setmeta -h "content-disposition:attachment" gs://BUCKET_NAME/**

Related

How to generate sitemap on user-generated content site in express js?

I'm creating a user-generated content site using expressjs. How can I add the URL of these generated content to the sitemap and get it done automatically?
It also needs to be removed from these URLs via the sitemap when the user deletes the account or deletes the content.
I tried the sitemap builder npm packages created for express js, but none of them worked as I wanted, or the intended use was not the same as my intended use.
I am unsure if I understood your question, so I assume the following:
Your users can generate new URLs that you want to publish in an sitemap.xml that is returned from a specific endpoint right?
If so I'd suggest to use the sitemap.js package. However this package still needs a list of URLs and the metadata you want to deliver.
You could just save the URLs and the metadata to a database table, the filesystem, or whatever data storage you use. Every time content is generated or deleted you also update your URLs list there.
Now, if someone accesses the sitemap endpoint, URLs are read from storage and sitemap.js generates an XML. Goal achieved!

AWS Lambda Function - Image Upload - Process Review

I'm trying to better understand how the overall flow should work with AWS Lambda and my Web App.
I would like to have the client upload a file to a public bucket (completely bypassing my API resources), with the client UI putting it into a folder for their account based on a GUID. From there, I've got lambda to run when it detects a change to the public bucket, then resizing the file and placing it into the processed bucket.
However, I need to update a row in my RDS Database.
Issue
I'm struggling to understand the best practice to use for identifying the row to update. Should I be uploading another file with the necessary details (where every image upload consists really of two files - an image and a json config)? Should the image be processed, and then the client receives some data and it makes an API request to update the row in the database? What is the right flow for this step?
Thanks.
You should use a pre-signed URL for the upload. This allows your application to put restrictions on the upload, such as file type, directory and size. It means that, when the file is uploaded, you already know who did the upload. It also prevents people from uploading randomly to the bucket, since it does not need to be public.
The upload can then use an Amazon S3 Event to trigger the Lambda function. The filename/location can be used to identify the user, so the database can be updated at the time that the file is processed.
See: Uploading Objects Using Presigned URLs - Amazon Simple Storage Service
I'd avoid uploading a file directly to S3 bypassing the API. Uploading file from your API allows you to control type of file, size etc as well as you will know who exactly is uploading the file (API authid or user id in API body). This is also a security risk to open a bucket to public for writes.
Your API clients can then upload the file via API, which then can store file on S3 (trigger another lambda for processing) and then update your RDS with appropriate meta-data for that user.

Is image or file being always downloaded from Google Cloud Storage on click?

Please help me to understand the following, I have a node.js app which I want to run on Google Cloud App Engine, this app will contain some images which are planned to be stored on Google Cloud Storage. On my sample app once I upload an image and get a url (mediaLink or selfLink) image is being downloaded.
Why is that? Each download each click costs money I understand google, but is there any way to make url just show images NOT to be downloaded?
Saving a file from Google Cloud Storage is the same as displaying it. Both action require transferring the content of the image to the device for display or saving.
The action of displaying an image or popping up a save as dialog is controlled by HTTP headers. For example if you have the HTTP header content-type set incorrectly (not as an image) then some browsers will save the file. If you want your image files to be displayed as images set the headers correctly for the type of picture. For PNG files set the header contenty-type: image/png.
You can also force a download with the content-disposition: attachment header.
In summary, it does not matter if you are displaying an image or saving it to local storage, it will cost you money. Both actions requiring downloading (transferring) the contents of the file across the Internet.

How can I build a Kentico media selector to return media file GUID when integrating with Azure storage?

We have a Kentico 9 instance with media library integrated with Azure blob storage. This means that Kentico's default media selector form control returns an absolute URL of the Azure blob. However, as well as the URL, I need to access the media file info object itself to get additional properties (such as file width).
In the past when using Kentico's own file storage I've been able to build a custom media selector and pull the media file GUID from the returned URL. However, this isn't possible when integrating with Azure storage. Does anyone have any ideas how I might get the file ID or GUID without building my own media selector from scratch?
How about using custom form control with an UniSelector control to which you would pass all files from your azure media library?
You could get the files using something like:
var mediaLibrary = MediaLibraryInfoProvider.GetMediaLibraryInfo("MyAzureLibrary", "SiteName");
var mediaFiles = MediaFileInfoProvider.GetMediaFiles()
.Columns("FileName", "FilePath", "FileGUID")
.WhereEquals("FileLibraryID", mediaLibrary.LibraryID);
This way you could get "nice" dialog that would list all the files in particular folder and you could set up the UniSelector to store GUIDS of those files instead of their paths.
The disadvantage of this is that you don't get the nice tree view as you do in Media library. Once you have the GUID of file, you can then reconstruct the full absolute URL.
If you wanted to have the tree view you could use the CMSTreeView control, but it is more complicated and you would probably need to place it inside a modal window so that it doesn't overflow with other content. Modifying the built-in MediaSelector form control is not really possibly because its under the source code.
Try to enable the following setting:
Content -> Media -> Security -> Check files permissions
In that case inserted media URLs should remain as permanent URLs (because the media handler needs to check the permissions) and you should be able to extract the GUID from the URL as you are used to.

Amazon S3 Browser Based Upload - Prevent Overwrites

We are using Amazon S3 for images on our website and users upload the images/files directly to S3 through our website. In our policy file we ensure it "begins-with" "upload/". Anyone is able to see the full urls of these images since they are publicly readable images after they are uploaded. Could a hacker come in and use the policy data in the javascript and the url of the image to overwrite these images with their data? I see no way to prevent overwrites after uploading once. The only solution I've seen is to copy/rename the file to a folder that is not publicly writeable but that requires downloading the image then uploading it again to S3 (since Amazon can't really rename in place)
If I understood you correctly The images are uploaded to Amazon S3 storage via your server application.
So the Amazon S3 write permission has only your application. Clients can upload images only throw your application (which will store them on S3). Hacker can only force your application to upload image with same name and rewrite the original one.
How do you handle the situation when user upload a image with a name that already exists in your S3 storage?
Consider following actions:
First user upload a image some-name.jpg
Your app stores that image in S3 under name upload-some-name.jpg
Second user upload a image some-name.jpg
Will your application overwrite the original one stored in S3?
I think the question implies the content goes directly through to S3 from the browser, using a policy file supplied by the server. If that policy file has set an expiration, for example, one day in the future, then the policy becomes invalid after that. Additionally, you can set a starts-with condition on the writeable path.
So the only way a hacker could use your policy files to maliciously overwrite files is to get a new policy file, and then overwrite files only in the path specified. But by that point, you will have had the chance to refuse to provide the policy file, since I assume that is something that happens after authenticating your users.
So in short, I don't see a danger here if you are handing out properly constructed policy files and authenticating users before doing so. No need for making copies of stuff.
actually S3 does have a copy feature that works great
Copying Amazon S3 Objects
but as amra stated above, doubling your space by copying sounds inefficient
mybe itll be better to give the object some kind of unique id like a guid and set additional user metadata that begin with "x-amz-meta-" for some more information on the object, like the user that uploaded it, display name, etc...
on the other hand you could always check if the key exists already and prompt for an error

Resources