UNPKG

@ki1r0y/signed-cloud-server

Version:

Basic cloud storage in which contents are cryptographically signed, using distributed-storage as a co-dependency.

32 lines (30 loc) 1.52 kB
import fs from 'node:fs/promises'; import path from 'node:path'; import {tagPath, mkdir} from './tagPath.mjs'; export async function storeVerifiedBody(req, res, next) { // Store verified body by either writing it to a file or removing the file (if there's no content). // Requires req.verified to be set. let {body} = req, {collectionName, tag} = req.params, pathname = tagPath(collectionName, tag), verifiedContent = req.verified.text; if (verifiedContent) { let directory = path.dirname(pathname) await mkdir(directory); await fs.writeFile(pathname, body, {flush: true}); } else if (req.verified) { // Bogus data can't be used to delete things. // Subtle: If there's no verifiedContent, we delete the file. But some implementations of unlink resolve before // the file system has truly flushed the data. That can result in (await Security.destroy(); await Security.retrieve()) // producing the old data! We handle this by moving the file out of the way and then deleting that. let alt = pathname + '.DEL'; // Because of request queueing, overlapping requests to the same tag will have "completed" unlink before next rename. await fs.rename(pathname, alt); await fs.unlink(alt); let directory = path.dirname(pathname), base = tagPath(collectionName, ''); while (directory !== base && !(await fs.readdir(directory)).length) { await fs.rmdir(directory, {maxRetries: 3}); directory = path.dirname(directory); } } next(); }