import type { HttpContext } from '@adonisjs/core/http'; import File from '#models/file'; import { StatusCodes } from 'http-status-codes'; import * as fs from 'fs'; import * as path from 'path'; import { DateTime } from 'luxon'; // node ace make:controller Author export default class FileController { // @Get("download/:id") public async findOne({ response, params }: HttpContext) { const id = params.id; // const file = await File.findOrFail(id); // Load file with its related dataset to check embargo const file = await File.query() .where('id', id) .preload('dataset') // or 'dataset' - whatever your relationship is named .firstOrFail(); if (!file) { return response.status(StatusCodes.NOT_FOUND).send({ message: `Cannot find File with id=${id}.`, }); } // Check embargo date const dataset = file.dataset; // or file.dataset if (dataset && this.isUnderEmbargo(dataset.embargo_date)) { return response.status(StatusCodes.FORBIDDEN).send({ message: `File is under embargo until ${dataset.embargo_date?.toFormat('yyyy-MM-dd')}`, }); } // Proceed with file download const filePath = '/storage/app/data/' + file.pathName; const ext = path.extname(filePath); const fileName = file.label + ext; try { fs.accessSync(filePath, fs.constants.R_OK); //| fs.constants.W_OK); // console.log("can read/write:", path); response .header('Cache-Control', 'no-cache private') .header('Content-Description', 'File Transfer') .header('Content-Type', file.mimeType) .header('Content-Disposition', 'inline; filename=' + fileName) .header('Content-Transfer-Encoding', 'binary') .header('Access-Control-Allow-Origin', '*') .header('Access-Control-Allow-Methods', 'GET,POST'); response.status(StatusCodes.OK).download(filePath); } catch (err) { // console.log("no access:", path); response.status(StatusCodes.NOT_FOUND).send({ message: `File with id ${id} doesn't exist on file server`, }); } } /** * Check if the dataset is under embargo * Compares only dates (ignoring time) for embargo check * @param embargoDate - The embargo date from dataset * @returns true if under embargo, false if embargo has passed or no embargo set */ private isUnderEmbargo(embargoDate: DateTime | null): boolean { // No embargo date set - allow download if (!embargoDate) { return false; } // Get current date at start of day (00:00:00) const today = DateTime.now().startOf('day'); // Get embargo date at start of day (00:00:00) const embargoDateOnly = embargoDate.startOf('day'); // File is under embargo if embargo date is after today // This means the embargo lifts at the start of the embargo date return embargoDateOnly >= today; } }