Add path builder

This commit is contained in:
KernelDeimos 2024-05-16 18:24:50 -04:00
parent 5031cea040
commit e3f57ee20e
2 changed files with 69 additions and 2 deletions

View File

@ -26,6 +26,7 @@ const auth = require('../middleware/auth.js');
const { generate_puter_page_html } = require('../temp/puter_page_loader');
const { Context } = require('../util/context');
const { DB_READ } = require('../services/database/consts');
const { PathBuilder } = require('../util/pathutil.js');
let auth_user;
@ -246,6 +247,7 @@ router.all('*', async function(req, res, next) {
// /assets/
// ------------------------
else if (path.startsWith('/assets/')) {
path = PathBuilder.resolve(path);
return res.sendFile(path, { root: __dirname + '../../public' }, function (err) {
if (err && err.statusCode) {
return res.status(err.statusCode).send('Error /public/')
@ -338,7 +340,7 @@ router.all('*', async function(req, res, next) {
// /dist/...
else if(path.startsWith('/dist/') || path.startsWith('/src/')){
path = _path.resolve(path);
path = PathBuilder.resolve(path);
return res.sendFile(path, {root: config.assets.gui}, function(err){
if(err && err.statusCode){
return res.status(err.statusCode).send('Error /gui/dist/')
@ -348,6 +350,7 @@ router.all('*', async function(req, res, next) {
// All other paths
else{
path = PathBuilder.resolve(path);
return res.sendFile(path, {root: _path.join(config.assets.gui, 'src')}, function(err){
if(err && err.statusCode){
return res.status(err.statusCode).send('Error /gui/')
@ -364,7 +367,11 @@ router.all('*', async function(req, res, next) {
subdomain === 'draw' || subdomain === 'camera' || subdomain === 'recorder' ||
subdomain === 'dev-center' || subdomain === 'terminal'){
let root = _path.join(__dirname, config.defaultjs_asset_path, 'apps', subdomain);
let root = PathBuilder
.add(__dirname)
.add(config.defaultjs_asset_path, { allow_traversal: true })
.add('apps').add(subdomain)
.build();
if ( subdomain === 'docs' ) root += '/dist';
root = _path.normalize(root);

View File

@ -0,0 +1,60 @@
const { AdvancedBase } = require("@heyputer/puter-js-common");
/**
* PathBuilder implements the builder pattern for building paths.
* This makes it clear which path fragments are allowed to traverse
* to parent directories.
*/
class PathBuilder extends AdvancedBase {
static MODULES = {
path: require('path'),
}
constructor() {
super();
this.path_ = '';
}
static create () {
return new PathBuilder();
}
static add (fragment, options) {
return PathBuilder.create().add(fragment, options);
}
static resolve (fragment) {
const p = PathBuilder.create();
const require = p.require;
const node_path = require('path');
fragment = node_path.resolve(fragment);
return p.add(fragment).build();
}
add (fragment, options) {
options = options || {};
if ( ! options.allow_traversal ) {
fragment = fragment.replace(/(\.\.\/|\.\.\\)/g, '');
if ( fragment === '..' ) {
fragment = '';
}
}
const require = this.require;
const node_path = require('path');
this.path_ = this.path_
? node_path.join(this.path_, fragment)
: fragment;
return this;
}
build () {
return this.path_;
}
}
module.exports = {
PathBuilder,
};