tus/tus-node-server

How to get final name back in client?

tbunique opened this issue · 4 comments

Hello,

new Server({
    path: '/files',
    datastore: s3Store,
    namingFunction(req, metadata) {
        const newName = removeSuperfluousChars(metadata.filename);
        return newName;
    },
    onUploadCreate(req, res, upload) {
        const isAuthorised = checkSignature(upload.metadata);

        if (isAuthorised) {
            return res;
        }

        throw {
            status_code: 400
        };
    },
    onUploadFinish(req, res, upload) {
        deleteInfoFile(upload.metadata.filename);
        // res.setHeader('file-location', upload.id);
        return res;
    }
});

I'm using TUS to enable our clients to upload files into our S3 but there is something I'm missing. I use namingFunction to remove any weird characters the client would have in their name before storing it.
But I can't find how to send that clean name back to the client. I've tried modifying the headers in the onUploadFinish method and the header is correctly sent but CORS blocks the browser from reading the new name. I've checked the TUS source code and it seems I can't add anything to the EXPOSED_HEADERS.

I could move the renaming logic to the browser but I'd rather not the client being able to reintroduce weird characters.

Thanks in advance for any advice!

Hi, you shouldn't use namingFunction to change the default unique ID to a non-unique file name. This will cause file corruption sooner or later if people upload files with the same name!

What probably makes most sense is to have #594, then you can change the file name in the metadata and the store will save that new metadata. You can keep the actual files uniquely generated. In tus in generally works like this, original file name in the .info or .json file and a unique file adjacent to it.

Performing a HEAD request will send back the metadata whenever the client likes to know it.

I see, thanks 👍

I'm starting to think maybe tus is not the best for my use case. I want users to be able to overwrite existing files as they handle their own files. That's why I need to display the real file names without doing any HEAD requests (or querying my db where I would have stored the real hierarchy).

You can override files, you just want to do it safely and explicitly. If you only use namingFunction without extra logic that puts each user's files in their own folder, a user can corrupt other user's files.

You can remove the old file in onUploadFinish to "override" it. But as of now, you would need to perform a HEAD to see the changes. It's not ideal but it's not going to be a problem either I reckon.

In a future version of the tus spec, it would be nice to send back Upload-Metadata in the POST request.

I see what you mean.

I do have that extra logic elsewhere:

  • Browser sends initial request to other server
  • I check auth and return path to folder where user can upload their file
  • Browser initiates real transfer request to tus server and also sends filename and path with the metadata (path is protected with hmac so user can't tamper with it)
  • Naming function is used to put the file with real name in correct folder

I should have put my complete code in my initial example, apologies.