fix(mindspace): 公开页上传图片物化到 static 路径供转发访问

Finish 同步与首次访问时将私有资产 API 图片复制到 public/.tmp-images,
避免其他用户转发链接后因无登录态无法加载页面内图片。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-06 17:03:47 +08:00
parent 1077dd9b97
commit 0ae7a6a677
5 changed files with 194 additions and 2 deletions
+39
View File
@@ -14,6 +14,7 @@ import {
findPublishHtml,
injectHtmlBaseHref,
materializePrivateAssetsInWorkspaceHtml,
materializePrivateAssetsInPublicHtmlFiles,
repairMissingHtmlAssetReferences,
resolveClosestHtmlRelativePath,
resolveChatSaveAnalysis,
@@ -226,6 +227,44 @@ test('materializePrivateAssetsInWorkspaceHtml copies images to public/.tmp-image
await fs.stat(path.join(publishDir, '.tmp-images', `${assetId}.jpg`));
});
test('materializePrivateAssetsInPublicHtmlFiles rewrites referenced public html files', async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-chat-save-materialize-batch-'));
const storageRoot = path.join(root, 'storage');
const assetId = '44444444-4444-4444-8444-444444444444';
const userId = USER_ID;
const storageKey = `users/${userId}/assets/${assetId}/versions/v1`;
const sourcePath = path.join(storageRoot, storageKey);
await fs.mkdir(path.dirname(sourcePath), { recursive: true });
await fs.writeFile(sourcePath, Buffer.from([0xff, 0xd8, 0xff, 0xd9]));
const publishDir = path.join(root, 'MindSpace', userId);
const htmlRelativePath = 'public/share.html';
const htmlPath = path.join(publishDir, htmlRelativePath);
await fs.mkdir(path.dirname(htmlPath), { recursive: true });
const html = `<!doctype html><img src="/api/mindspace/v1/assets/${assetId}/download?inline=1">`;
await fs.writeFile(htmlPath, html, 'utf8');
const pool = {
query: async () => [
[{ id: assetId, mime_type: 'image/jpeg', original_filename: 'hero.jpg', storage_key: storageKey }],
],
};
const result = await materializePrivateAssetsInPublicHtmlFiles({
pool,
storageRoot,
h5Root: root,
userId,
publishDir,
relativePaths: [htmlRelativePath],
});
assert.equal(result.materialized.length, 1);
assert.equal(result.materialized[0].relativePath, htmlRelativePath);
const saved = await fs.readFile(htmlPath, 'utf8');
assert.match(saved, /\.tmp-images\/44444444-4444-4444-8444-444444444444\.jpg/);
});
test('repairMissingHtmlAssetReferences swaps invalid html asset ids from chat message', async () => {
const validId = '22222222-2222-4222-8222-222222222222';
const invalidId = '33333333-3333-4333-8333-333333333333';