From 4643e9f8385be046bfad7054d669f957bd07dc9f Mon Sep 17 00:00:00 2001 From: tdurieux Date: Sun, 6 Sep 2026 09:18:28 +0200 Subject: [PATCH] fix: preserve and anonymize truncated folder warnings --- src/core/Repository.ts | 5 +++-- src/server/routes/repository-public.ts | 5 ++++- test/production-regressions.test.js | 12 ++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/core/Repository.ts b/src/core/Repository.ts index 2cf7d48..093956a 100644 --- a/src/core/Repository.ts +++ b/src/core/Repository.ts @@ -163,11 +163,12 @@ export default class Repository { } if (!hasFile || opt.force) { await FileModel.deleteMany({ repoId: this.repoId }).exec(); - const files = await this.source.getFiles(opt.progress); + const source = this.source; + const files = await source.getFiles(opt.progress); files.forEach((f) => (f.repoId = this.repoId)); await FileModel.insertMany(files); - const sourceWithTruncation = this.source as unknown as { + const sourceWithTruncation = source as unknown as { truncatedFolderList?: string[]; }; if (Array.isArray(sourceWithTruncation.truncatedFolderList)) { diff --git a/src/server/routes/repository-public.ts b/src/server/routes/repository-public.ts index 5092696..56c31d3 100644 --- a/src/server/routes/repository-public.ts +++ b/src/server/routes/repository-public.ts @@ -1,3 +1,4 @@ +import { anonymizePath } from "../../core/anonymize-utils"; import * as express from "express"; import config from "../../config"; import got from "got"; @@ -389,7 +390,9 @@ router.get( isAdmin: user?.isAdmin === true, isOwner: user?.id == repo.model.owner, hasWebsite: !!repo.options.page && !!repo.options.pageSource, - truncatedFolders: repo.model.truncatedFolders || [], + truncatedFolders: (repo.model.truncatedFolders || []).map((path) => + anonymizePath(path, repo.options.terms || []) + ), // Submodule contents are not included in GitHub archives/trees, so // they end up as empty folders in the anonymized repository. Surface // a warning in the explorer when the repository uses submodules (#737). diff --git a/test/production-regressions.test.js b/test/production-regressions.test.js index 8709e48..73e370f 100644 --- a/test/production-regressions.test.js +++ b/test/production-regressions.test.js @@ -144,6 +144,18 @@ describe("production regressions", function () { } catch (error) { expect(error.message).to.equal("token_expired"); } }); + it("retains truncation warnings from the source instance that fetched the tree", async function () { + const FileModel = require("../src/core/model/files/files.model").default; + stub(db, "isConnected", false); + for (const method of ["exists", "deleteMany", "find"]) stub(FileModel, method, () => ({ exec: async () => method === "find" ? [] : null })); + stub(FileModel, "insertMany", async () => []); + const repo = new Repository(new RepoModel({ repoId: "repo", options: {} })); + repo.computeSize = async () => {}; + Object.defineProperty(repo, "source", { get() { return { truncatedFolderList: [], async getFiles() { this.truncatedFolderList = ["private/folder"]; return []; } }; } }); + await repo.files({ force: true }); + expect(repo.model.truncatedFolders).to.deep.equal(["private/folder"]); + }); + function response() { return { headers: {}, header(key, value) { this.headers[key] = value; return this; }, contentType() { return this; }, status(value) { this.statusCode = value; return this; }, end() {}, send() {} };