0

I want a make an API that will take a file or folder path from the user and upload it to AWS s3 I made progress but

when the user gives a file path it's searching the file path in the server, not in the user's pc

I know I made a mistake but I don't know how to connect API from the users pc and get access to system files

here is code for the post route

router.post("/create/:id", auth, async (req, res) => {
  try {
    let form = new multiparty.Form();
    form.parse(req, async (err, fields, files) => {
      console.log(fields);
      console.log(files);
      //check if user has access to project
      const user_id = req.userId;
      const project_id = req.params.id;
      const user_access = await check_user_access_project(user_id, project_id);
      const user = await User.findById(user_id);
      const project = await Project.findById(project_id);
      if (user_access === 1) {
        //create version
        const version = new Version({
          project_id: project_id,
          user_id: user_id,
          versionName: fields.versionName[0],
          version_description: fields.versionDescription[0],
          version_file: [],
        });
        const version_data = await version.save();
        console.log(version_data);

        let version_id = version_data._id;

        //sync folders to s3
        const version_folder_path = fields.files_path[0];
        let key = `${user.firstName}_${user_id}/${project.projectName}/${fields.versionName[0]}`;
        const version_folder_list = await sync_folders(
          version_folder_path,
          key
        );

        console.log("version folder list", version_folder_list);

        //update version with version folders
        await Version.findByIdAndUpdate(
          version_id,
          {
            $set: {
              version_file: version_folder_list,
            },
          },
          { new: true }
        );
        //wait for version update
        await version.save();

        //send response
        res.json({
          success: true,
          version: version_data,
        });
      } else {
        res.status(401).json({
          success: false,
          message: "User does not have access to project",
        });
      }
    });
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});

here is the folder sync code

const sync_folders = async (folder_path, key) => {
  function getFiles(dir, files_) {
    files_ = files_ || [];
    var files = fs.readdirSync(dir);
    for (var i in files) {
      var name = dir + "/" + files[i];
      if (fs.statSync(name).isDirectory()) {
        getFiles(name, files_);
      } else {
        files_.push(name);
      }
    }
    return files_;
  }

  const files = getFiles(folder_path);
  console.log(files);
  const fileData = [];
  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    console.log(file);

    const fileName = file.split("/").pop();
    const fileType = file.split(".").pop();
    const fileSize = fs.statSync(file).size;
    const filePath = file;

    const fileBuffer = fs.readFileSync(filePath);

    //folder is last part of folder path (e.g. /folder1/folder2/folder3)
    const folder = folder_path.split("/").pop();

    console.log("folder: " + folder);
    //split filepath
    const filePath_ = filePath.split(folder).pop();

    let filekey = key + "/" + folder + filePath_;

    console.log("filekey: " + filekey);

    const params = {
      Bucket: bucket,
      Key: filekey,
      Body: fileBuffer,
      ContentType: fileType,
      ContentLength: fileSize,
    };
    const data = await s3.upload(params).promise();
    console.log(data);
    fileData.push(data);
  }

  console.log("file data", fileData);
  console.log("files uploaded");
  return fileData;
};

if some buddy can help me pls I need your help

Ajay Singh
  • 11
  • 1
  • 1
    Hopefully this is obvious to you, but a server-side application cannot typically list files or folders on the web client's machine. If I understand what you're asking for, the user visiting your web page needs to attach files and then [upload them](https://stackoverflow.com/questions/8659808/how-does-http-file-upload-work) to your server. Or you need to do this outside of a web page. – jarmod Jun 01 '22 at 18:27
  • I need to upload a full folder form user and upload it to s3 – Ajay Singh Jun 02 '22 at 02:54
  • First you need to solve the problem of the client selecting a folder and your client-side code enumerating the contents of the folder so read [this](https://stackoverflow.com/a/52332992/271415) and look at dropzone,js, or similar, for that. Second, you need to upload all the files to S3. You can do that by POSTing their contents one-by-one to your server and from there store into S3, or your server can send the client a series of S3 pre-signed URLs and the client can directly POST the file contents to those pre-signed URLs (which are in S3, not your server). This is not a trivial task, FYI. – jarmod Jun 02 '22 at 10:35
  • You might also look at available options such as [S3Browser](https://s3browser.com/), [SFTP](https://aws.amazon.com/blogs/aws/new-aws-transfer-for-sftp-fully-managed-sftp-service-for-amazon-s3/), and [awscli sync](https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html) and others but for those your users would need to supply AWS credentials (which may be out of scope for your project, I don't know). – jarmod Jun 02 '22 at 10:38
  • thank you sir its really helpful i am trying it – Ajay Singh Jun 02 '22 at 14:25

1 Answers1

0

You need to post the item in a form rather than just putting the directory path of user in and then upload the result to your s3 bucket.

This might be a good start if you're new to it:

https://www.w3schools.com/nodejs/nodejs_uploadfiles.asp