feat(storage): serve files from disks that are not public
A disk without a base URL now has a way to reach the browser: FileStore::openStream() and the /file/{id} route stream it, and the URL a module renders switches to that route on its own — moving a directory of attachments onto a private disk changes nothing in the modules.
That is what a private disk is for. On the public disk anybody who has the address has the file forever, whatever the site decides afterwards; on a private one the paths cannot be guessed or listed, and a file stops being reachable the moment its row is deleted. Who may see a given attachment is still not asked — three modules relate files to their records in three different ways, so there is nothing to ask yet.
That is what a private disk is for. On the public disk anybody who has the address has the file forever, whatever the site decides afterwards; on a private one the paths cannot be guessed or listed, and a file stops being reachable the moment its row is deleted. Who may see a given attachment is still not asked — three modules relate files to their records in three different ways, so there is nothing to ask yet.