node.jsgoogle-cloud-storagecloud-storage

How to mark a file private before it's uploaded to Google Cloud Storage?


I'm using @google-cloud/storage package and generating signed url to upload file like this:

const path = require("path");
const { Storage } = require("@google-cloud/storage");
const GOOGLE_CLOUD_KEYFILE = path.resolve(
  __dirname + "/../gcloud_media_access.json"
);

const storage = new Storage({
  keyFilename: GOOGLE_CLOUD_KEYFILE,
});
exports.uploadUrlGCloud = async (bucketName, key, isPrivate = false) => {

  let bucket = storage.bucket(bucketName);
  let file = bucket.file(key);

  const options = {
    version: "v4",
    action: "write",
    expires: Date.now() + 15 * 60 * 1000 // 15 minutes
  };
  

  let signedUrl = (await file.getSignedUrl(options))[0];
  if(isPrivate){
    await file.makePrivate({strict: true});
  }

  return signedUrl;
};

However when I call this function like this:

const url = await uploadUrlGCloud(bucket, key, true);

I'm getting 404 api error like this:

ApiError: No such object: testbucket/account/upload/4aac0fb0-92dd-11eb-8723-6b3ad09f80fa_demo.jpg

What I want to ask is is there a way to generate the signedUrl private? Before the file is uploaded, I want to mark it as private and prevent public access.

Edit:

I uploaded a file to the created signed URL, and made makePrivate again to the uploaded file. This time I didn't get any errors. However, when I checked the file again, I realized that is still public.

This is the function I tried to make file private:

const makeFilePrivate = async (bucketName, key) => {

  return new Promise((resolve, reject) => {

    let bucket = storage.bucket(bucketName);
    let file = bucket.file(key);
  
    try {
  
      file.makePrivate({strict: true}, err => {
        
        if(!err) {
          resolve(file.isPublic());
        } else
        reject(err);

      })
  
    } catch (err) {
  
      reject(err);
  
    }

  }) 
};
console.log(await makeFilePrivate(bucket, remotePath));
// True

Solution

  • You can't make the objects of a public bucket private due to the way how IAM and ACLs interact with one another.