From fb1e2f21fb67aefe0602f6c978199c7cd019bbf7 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Wed, 19 Jun 2024 02:03:02 -0400 Subject: [PATCH] feat: start directory index frame --- .../backend/src/routers/hosting/puter-site.js | 37 ++++++++++++++++++- .../src/services/PuterHomepageService.js | 2 + .../backend/src/services/WebServerService.js | 6 ++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/routers/hosting/puter-site.js b/packages/backend/src/routers/hosting/puter-site.js index 2e94d85b..fbf9ce5f 100644 --- a/packages/backend/src/routers/hosting/puter-site.js +++ b/packages/backend/src/routers/hosting/puter-site.js @@ -27,10 +27,13 @@ const { LLRead } = require("../../filesystem/ll_operations/ll_read"); const { Actor, UserActorType, SiteActorType } = require("../../services/auth/Actor"); const APIError = require("../../api/APIError"); +const AT_DIRECTORY_NAMESPACE = '4aa6dc52-34c1-4b8a-b63c-a62b27f727cf'; + class PuterSiteMiddleware extends AdvancedBase { static MODULES = { path: require('path'), mime: require('mime-types'), + uuidv5: require('uuid').v5, } install (app) { app.use(this.run.bind(this)); @@ -66,9 +69,39 @@ class PuterSiteMiddleware extends AdvancedBase { const context = Context.get(); const services = context.get('services'); + + const get_username_site = (async () => { + if ( ! subdomain.endsWith('.at') ) return; + const parts = subdomain.split('.'); + if ( parts.length !== 2 ) return; + const username = parts[0]; + if ( ! username.match(config.username_regex) ) { + return; + } + const svc_fs = services.get('filesystem'); + const index_node = await svc_fs.node(new NodePathSelector( + `/${username}/Public/index.html` + )); + const node = await svc_fs.node(new NodePathSelector( + `/${username}/Public` + )); + if ( ! await index_node.exists() ) return; + + return { + name: username + '.at', + uuid: this.modules.uuidv5(username, AT_DIRECTORY_NAMESPACE), + root_dir_id: await node.get('mysql-id'), + }; + }) + + const site = + await get_username_site() || + await (async () => { + const svc_puterSite = services.get('puter-site'); + const site = await svc_puterSite.get_subdomain(subdomain); + return site; + })(); - const svc_puterSite = services.get('puter-site'); - const site = await svc_puterSite.get_subdomain(subdomain); if ( site === null ) { return res.status(404).send('Subdomain not found'); } diff --git a/packages/backend/src/services/PuterHomepageService.js b/packages/backend/src/services/PuterHomepageService.js index 32d32e52..cdb86a81 100644 --- a/packages/backend/src/services/PuterHomepageService.js +++ b/packages/backend/src/services/PuterHomepageService.js @@ -75,6 +75,8 @@ class PuterHomepageService extends BaseService { app_name_regex: config.app_name_regex, app_name_max_length: config.app_name_max_length, app_title_max_length: config.app_title_max_length, + hosting_domain: config.static_hosting_domain + + (config.pub_port !== 80 && config.pub_port !== 443 ? ':' + config.pub_port : ''), subdomain_regex: config.subdomain_regex, subdomain_max_length: config.subdomain_max_length, domain: config.domain, diff --git a/packages/backend/src/services/WebServerService.js b/packages/backend/src/services/WebServerService.js index 03848d7a..cfcd5794 100644 --- a/packages/backend/src/services/WebServerService.js +++ b/packages/backend/src/services/WebServerService.js @@ -314,7 +314,11 @@ class WebServerService extends BaseService { // Validate host header against allowed domains to prevent host header injection // https://www.owasp.org/index.php/Host_Header_Injection app.use((req, res, next)=>{ - const allowedDomains = [config.domain.toLowerCase(), config.static_hosting_domain.toLowerCase()]; + const allowedDomains = [ + config.domain.toLowerCase(), + config.static_hosting_domain.toLowerCase(), + 'at.' + config.static_hosting_domain.toLowerCase(), + ]; // Retrieve the Host header and ensure it's in a valid format const hostHeader = req.headers.host;