浏览代码

Merge branch 'main' of https://github.com/HeyPuter/puter into main

Nariman Jelveh 11 月之前
父节点
当前提交
892750788b

+ 35 - 2
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');
         }

+ 2 - 0
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,

+ 5 - 1
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;

+ 26 - 0
src/UI/UIWindow.js

@@ -337,6 +337,32 @@ async function UIWindow(options) {
             if(options.is_dir){
                 // Detail layout header
                 h += window.explore_table_headers();
+                
+                // Maybe render iframe for users public directory
+                (() => {
+                    if ( options.is_saveFileDialog || options.is_openFileDialog || options.is_directoryPicker ) {
+                        return false;
+                    }
+                    
+                    if ( ! options.path || ! options.path.startsWith('/') ) { // sus
+                        return false;
+                    }
+                    
+                    const components = options.path.slice(1).split('/');
+
+                    console.log('components???', components);
+                    if ( components.length === 2 && components[1] === 'Public' ) {
+                        const username = components[0];
+                        h += `<iframe
+                            style="display:block;width:100%"
+                            tabindex="-1"
+                            frameborder="0"
+                            src="http://${username}.at.${window.hosting_domain}"
+                            height=150
+                            ></iframe>
+                        `;
+                    }
+                })();
 
                 // Add 'This folder is empty' message by default
                 h += `<div class="explorer-empty-message">This folder is empty</div>`;