tus / tus-node-server

Node.js tus server, standalone or integrable in any framework, with disk, S3, and GGC stores.
https://tus.io/
MIT License
795 stars 197 forks source link

How to get final name back in client? #598

Closed tbunique closed 4 months ago

tbunique commented 4 months ago

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!

Murderlon commented 4 months ago

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.

tbunique commented 4 months ago

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).

Murderlon commented 4 months ago

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.

tbunique commented 4 months ago

I see what you mean.

I do have that extra logic elsewhere:

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