diff --git a/archive/js/app.js b/archive/js/app.js index 65b7728..4441fe5 100644 --- a/archive/js/app.js +++ b/archive/js/app.js @@ -138,11 +138,22 @@ var serverProjects = await resp.json(); if (Array.isArray(serverProjects) && serverProjects.length > 0 && serverProjects[0] && typeof serverProjects[0].name === 'string') { - serverNames = new Set(serverProjects.map(function(p) { return p.name; })); + // GET / Accept: application/json returns listing.FileInfo + // entries (not the legacy ProjectInfo shape): directory + // names carry a trailing "/", and the listing can include + // non-directory entries. Normalise to bare directory names + // so they match the slash-free projectFilter parsed from + // ?projects= (url-state.js). Without this, every URL-listed + // project misses the intersection below → "no access" + // banner + empty scan. + var bareName = function (p) { return p.name.replace(/\/+$/, ''); }; + var isProjectDir = function (p) { return p.is_dir === true || /\/$/.test(p.name); }; + var projectEntries = serverProjects.filter(isProjectDir); + serverNames = new Set(projectEntries.map(bareName)); var titles = {}; - serverProjects.forEach(function (p) { + projectEntries.forEach(function (p) { if (p && typeof p.title === 'string' && p.title) { - titles[p.name] = p.title; + titles[bareName(p)] = p.title; } }); window.app.projectTitles = titles; diff --git a/archive/js/source.js b/archive/js/source.js index 5767675..9feb94d 100644 --- a/archive/js/source.js +++ b/archive/js/source.js @@ -402,10 +402,10 @@ } async function scanHttpRoot(scanRootUrl, rootUrl, callbacks) { - // Mode 1 — multi-project (?projects= set). Skip listing scanRootUrl entirely: - // the zddc-server returns a ProjectInfo array there (not a Caddy fileInfo - // listing), so iterating it as if it were a directory listing wouldn't work. - // Project URLs are deterministic — go straight to each one. + // Mode 1 — multi-project (?projects= set). Skip listing scanRootUrl + // entirely: project URLs are deterministic, so go straight to each one + // (the names in projectFilter, slash-normalised in app.js against the + // server's root listing). Avoids depending on the root listing's shape. if (window.app.projectFilter && window.app.projectFilter.size > 0) { const tasks = []; for (const name of window.app.projectFilter) {