Files
cloudron-box/src/routes/filemanager.js
T
Girish Ramakrishnan 4ed6fbbd74 eslint: add no-shadow
2026-02-18 08:18:37 +01:00

57 lines
2.1 KiB
JavaScript

import assert from 'node:assert';
import BoxError from '../boxerror.js';
import http from 'node:http';
import { HttpError } from '@cloudron/connect-lastmile';
import safe from 'safetydance';
import services from '../services.js';
function proxy(kind) {
assert(kind === 'mail' || kind === 'volume' || kind === 'app');
return async function (req, res, next) {
req.clearTimeout();
let id = null;
switch (kind) {
case 'app': id = `app-${req.params.id}`; break;
case 'volume': id = `volume-${req.params.id}`; break;
case 'mail': id = 'mail'; break;
}
const [error, addonDetails] = await safe(services.getContainerDetails('sftp', 'CLOUDRON_SFTP_TOKEN'));
if (error) return next(BoxError.toHttpError(error));
const searchParams = new URLSearchParams(req.url.slice(req.url.indexOf('?')+1));
searchParams.delete('access_token');
searchParams.append('access_token', addonDetails.token);
const filepath = req.params.filepath.join('/');
const opts = {
hostname: addonDetails.ip,
port: 3000,
path: `/files/${id}/${encodeURIComponent(filepath)}?${searchParams.toString()}`, // params[0] already contains leading '/'
method: req.method,
headers: req.headers
};
const sftpReq = http.request(opts, function (sftpRes) {
res.writeHead(sftpRes.statusCode, sftpRes.headers);
// note: these are intentionally not handled. response has already been written. do not forward to connect-lastmile
// sftpRes.on('error', (error) => next(new HttpError(500, `filemanager error: ${error.message} ${error.code}`)));
// sftpRes.on('end', () => next());
sftpRes.pipe(res);
});
sftpReq.on('error', (reqError) => next(new HttpError(424, `Unable to connect to filemanager: ${reqError.message} ${reqError.code}`)));
if (!req.readable) {
sftpReq.end();
} else {
req.pipe(sftpReq);
}
};
}
export default {
proxy,
};