Temporary File Download

Problem

Is there a service that creates basically a one-time download of a file, preferably something I can use from NodeJS?

I've done some research on FilePicker, and haven't found anything about regenerating the link it gives you for a file. There may be a way to do this with NodeJS, but I'm using Meteor at the same time so many Node things probably will conflict.

Problem courtesy of: Christian Stewart

Solution

Solution using Heroku Cloud and NodeJS Meteor Hooks

Heroku in particular is actually great for temporary file download links: they offer a "temporary scratchpad" filesystem that is reset every time the program restarts, and each running Node server cannot see the files other instances have created.

Each dyno gets its own ephemeral filesystem, with a fresh copy of the most recently deployed code. During the dyno’s lifetime its running processes can use the filesystem as a temporary scratchpad, but no files that are written are visible to processes in any other dyno and any files written will be discarded the moment the dyno is stopped or restarted.

Taken from the Heroku documentation: https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem

Thus, any files written to the "filesystem" will be temporary.

This allows for a very easy solution to this problem: you can simply use NodeJS filesystem manipulation to create temporary files on the server, serve them once (or for a limited time), and then remove them so they cannot be downloaded again.

This in combination with something like $.download() will make a seamless experience which in turn prevents unauthorized downloads.

Sample Code Soon

Solution courtesy of: Christian Stewart

Discussion

in addition to using the router package

in Meteor.startup you can add

var require = __meteor_bootstrap__.require;
fs = require( 'fs' );

the fs variable should be declared on the server only. the fs package is used by Meteor and does not need to be added separately.

once you have done this, you can create files with Meteor.uuid() as their name which makes them unique and very difficult to guess. It is also possible to delete the file after a certain amount of time by using Meteor.setTimeout

the question is: where do the files to be downloaded come from?

Discussion courtesy of: Dr Gorb

My recommendation would also be to add custom server-side logic to count # of uploads (or just flag a file as downloaded/not downloaded) and respond accordingly. The closest you could do with Filepicker.io would be using the security policies to restrict downloading the file to a specific time interval.

Discussion courtesy of: brettcvz

You could build it with meteor. Using meteor-router with meteorite & use server side routing to deliver the files.

You need a collection to keep track of downloaded files:

Server JS

var downloads = new Meteor.Collection("downloads");

//create a link
downloads.insert({url:"/mydownload.zip",downloaded:false})

Meteor.Router.add('/file/:id', 'GET', function(id) {
    download = downloads.findOne(id);
    if( download) {
       if(dowload.downloaded) {
           this.response.send("You've already downloaded me")
       }
       else
       {
           //I guess you could just redirect or stream the file for an extra layer of surety
           this.response.redirect(download.url);
       }
   }
});

On the client you can use /files/{{_id}} with _id of the file from downloads the person has as the link

Discussion courtesy of: Akshat

This recipe can be found in it's original form on Stack Over Flow.