fix: restore page links after delayed materialization
This commit is contained in:
@@ -94,6 +94,7 @@
|
|||||||
- `H5_USERS_ROOT` 同级的共享 `MindSpace/<userId>`
|
- `H5_USERS_ROOT` 同级的共享 `MindSpace/<userId>`
|
||||||
- 显式 `MEMIND_SHARED_PUBLISH_ROOT` / `GOOSED_SANDBOX_PUBLISH_ROOT`
|
- 显式 `MEMIND_SHARED_PUBLISH_ROOT` / `GOOSED_SANDBOX_PUBLISH_ROOT`
|
||||||
- 不得因为 Portal 运行在临时 worktree,而误删共享 session 工作区中的有效页面链接
|
- 不得因为 Portal 运行在临时 worktree,而误删共享 session 工作区中的有效页面链接
|
||||||
|
- 历史消息若已被替换成「页面生成未完成」占位文案,后续读取发现同名 HTML 已存在时必须恢复为可点击链接
|
||||||
|
|
||||||
### 守卫
|
### 守卫
|
||||||
|
|
||||||
|
|||||||
@@ -461,6 +461,8 @@ const PUBLIC_HTML_MARKDOWN_LINK_PATTERN =
|
|||||||
const MARKDOWN_LINK_PATTERN = /\[([^\]\n]*)\]\((https?:\/\/[^\s<>"')\]]+)\)/g;
|
const MARKDOWN_LINK_PATTERN = /\[([^\]\n]*)\]\((https?:\/\/[^\s<>"')\]]+)\)/g;
|
||||||
const PLAIN_HTML_URL_PATTERN = /https?:\/\/[^\s<>"')\]]+\.html/gi;
|
const PLAIN_HTML_URL_PATTERN = /https?:\/\/[^\s<>"')\]]+\.html/gi;
|
||||||
const INLINE_PUBLIC_HTML_PATH_PATTERN = /`((?:\.\/)?public\/[^`\s<>"')\]]+\.html)`/gi;
|
const INLINE_PUBLIC_HTML_PATH_PATTERN = /`((?:\.\/)?public\/[^`\s<>"')\]]+\.html)`/gi;
|
||||||
|
const MISSING_PUBLIC_HTML_NOTICE_PATTERN =
|
||||||
|
/(页面生成未完成,已阻止显示失效链接:([^()\n]+\.html)。)/g;
|
||||||
const USER_IDENTITY_BLOCK_PATTERN = /^\[用户身份\][\s\S]*?(?:\n{2,}|$)/;
|
const USER_IDENTITY_BLOCK_PATTERN = /^\[用户身份\][\s\S]*?(?:\n{2,}|$)/;
|
||||||
const IMAGE_URL_LINES_PATTERN = /\n*\[图片\d+]: [^\n]+/g;
|
const IMAGE_URL_LINES_PATTERN = /\n*\[图片\d+]: [^\n]+/g;
|
||||||
const TKMIND_VISION_NOTE_PATTERN = /\n*【TKMind 图片分析结果[\s\S]*$/;
|
const TKMIND_VISION_NOTE_PATTERN = /\n*【TKMind 图片分析结果[\s\S]*$/;
|
||||||
@@ -606,6 +608,13 @@ function rewriteOwnPublicationRouteLinks(text, currentUser) {
|
|||||||
|
|
||||||
export function sanitizePublicHtmlLinksInText(text, currentUser) {
|
export function sanitizePublicHtmlLinksInText(text, currentUser) {
|
||||||
let next = String(text ?? '').replace(
|
let next = String(text ?? '').replace(
|
||||||
|
MISSING_PUBLIC_HTML_NOTICE_PATTERN,
|
||||||
|
(match, filename) => {
|
||||||
|
const result = sanitizeOwnPublicHtmlRelativePath(`public/${path.posix.basename(filename)}`, currentUser);
|
||||||
|
return result ? `[${result.label}](${result.url})` : match;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
next = next.replace(
|
||||||
PUBLIC_HTML_MARKDOWN_LINK_PATTERN,
|
PUBLIC_HTML_MARKDOWN_LINK_PATTERN,
|
||||||
(match, label, url, owner, rawRelativePath) => {
|
(match, label, url, owner, rawRelativePath) => {
|
||||||
const result = sanitizeOwnPublicHtmlUrl(url, owner, rawRelativePath, currentUser);
|
const result = sanitizeOwnPublicHtmlUrl(url, owner, rawRelativePath, currentUser);
|
||||||
|
|||||||
@@ -219,6 +219,21 @@ test('sanitizePublicHtmlLinksInText finds pages in the workspace beside H5_USERS
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('sanitizePublicHtmlLinksInText restores a previously suppressed link after the page appears', () => {
|
||||||
|
const owner = `test-user-${Date.now()}-restored-link`;
|
||||||
|
const htmlPath = path.join(process.cwd(), 'MindSpace', owner, 'public', 'poem.html');
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(path.dirname(htmlPath), { recursive: true });
|
||||||
|
fs.writeFileSync(htmlPath, '<!doctype html><title>Poem</title>');
|
||||||
|
const text = '页面链接:\n(页面生成未完成,已阻止显示失效链接:poem.html。)';
|
||||||
|
const next = sanitizePublicHtmlLinksInText(text, { id: owner, username: 'john' });
|
||||||
|
assert.match(next, new RegExp(`\\[poem\\.html\\]\\([^)]*/MindSpace/${owner}/public/poem\\.html\\)`));
|
||||||
|
assert.doesNotMatch(next, /页面生成未完成/);
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(path.join(process.cwd(), 'MindSpace', owner), { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('sanitizePublicHtmlLinksInText canonicalizes wrong MindSpace public hosts', () => {
|
test('sanitizePublicHtmlLinksInText canonicalizes wrong MindSpace public hosts', () => {
|
||||||
const owner = `test-user-${Date.now()}-canonical-host`;
|
const owner = `test-user-${Date.now()}-canonical-host`;
|
||||||
const previousBase = process.env.H5_PUBLIC_BASE_URL;
|
const previousBase = process.env.H5_PUBLIC_BASE_URL;
|
||||||
|
|||||||
Reference in New Issue
Block a user