import crypto from 'node:crypto'; import { injectBeforeDocumentClosingBody } from './html-document-injection.mjs'; const PUBLIC_FILE_SHARE_SCRIPT = `(function(){ var root=document.querySelector('[data-mindspace-public-share]'); if(!root)return; var shareButton=root.querySelector('[data-action="share"]'); var captureButton=root.querySelector('[data-action="capture"]'); var plazaButton=root.querySelector('[data-action="plaza"]'); var wechatButton=root.querySelector('[data-action="wechat-draft"]'); var dialog=root.querySelector('[data-mindspace-public-share-dialog]'); var wechatDialog=root.querySelector('[data-mindspace-wechat-dialog]'); var plazaCancel=root.querySelector('[data-action="plaza-cancel"]'); var plazaConfirm=root.querySelector('[data-action="plaza-confirm"]'); var plazaAlreadyClose=root.querySelector('[data-action="plaza-already-close"]'); var plazaSuccessClose=root.querySelector('[data-action="plaza-success-close"]'); var plazaErrorClose=root.querySelector('[data-action="plaza-error-close"]'); var plazaAlreadyLink=root.querySelector('[data-plaza-already-link]'); var plazaSuccessLink=root.querySelector('[data-plaza-success-link]'); var plazaViews={ confirm:root.querySelector('[data-plaza-view="confirm"]'), loading:root.querySelector('[data-plaza-view="loading"]'), already:root.querySelector('[data-plaza-view="already"]'), success:root.querySelector('[data-plaza-view="success"]'), error:root.querySelector('[data-plaza-view="error"]') }; var status=root.querySelector('small'); var timer=null; var publishing=false; var checking=false; function setStatus(text,err,persist){ if(!status)return; status.textContent=text||''; status.classList.toggle('is-error',!!err); if(timer)clearTimeout(timer); if(text&&!persist)timer=setTimeout(function(){status.textContent='';status.classList.remove('is-error');},3200); } function cleanUrl(){var url=new URL(location.href);url.hash='';url.searchParams.delete('download');url.searchParams.delete('export');return url.toString();} function withParam(url,key,value){var next=new URL(url);next.searchParams.set(key,value);return next.toString();} function fallbackCopy(text){var ta=document.createElement('textarea');ta.value=text;ta.style.position='fixed';ta.style.left='-9999px';ta.style.opacity='0';document.body.appendChild(ta);ta.focus();ta.select();var ok=document.execCommand('copy');ta.remove();if(!ok)throw new Error('复制失败');} async function copyText(text){if(navigator.clipboard&&navigator.clipboard.writeText){try{await navigator.clipboard.writeText(text);return;}catch(e){}}fallbackCopy(text);} function workspaceRelativePath(){var parts=location.pathname.split('/').filter(Boolean);if(parts[0]==='MindSpace'&&parts.length>=3)return parts.slice(2).join('/');return'';} function showPlazaView(name){Object.keys(plazaViews).forEach(function(key){var view=plazaViews[key];if(view)view.hidden=key!==name;});} function openPlazaDialog(){if(!dialog)return;dialog.hidden=false;showPlazaView('loading');void refreshPlazaDialog();} function closePlazaDialog(){if(dialog)dialog.hidden=true;showPlazaView('confirm');} function apiErrorBody(payload){return payload&&(payload.error||payload)||{};} function resolvePlazaUrl(payload){var body=apiErrorBody(payload);if(body.plaza_url)return body.plaza_url;var details=body.details;if(details&&details.plaza_url)return details.plaza_url;var postId=details&&(details.post_id||details.postId);if(!postId)return'';return location.origin.replace(/:\\d+$/,'')+':3001/plaza/p/'+encodeURIComponent(postId);} function showAlreadyPublished(plazaUrl){showPlazaView('already');if(plazaAlreadyLink){if(plazaUrl){plazaAlreadyLink.href=plazaUrl;plazaAlreadyLink.hidden=false;}else{plazaAlreadyLink.hidden=true;}}} async function refreshPlazaDialog(){ if(checking)return; var relativePath=workspaceRelativePath(); if(!relativePath){showPlazaView('error');return;} checking=true; try{ var res=await fetch('/api/mindspace/v1/pages/quick-plaza-from-public-html/status?relative_path='+encodeURIComponent(relativePath),{credentials:'same-origin'}); var payload=await res.json().catch(function(){return{};}); if(!res.ok){ if(res.status===401)throw new Error('请先登录 MindSpace'); var errBody=apiErrorBody(payload); throw new Error(errBody.message||'无法检查发布状态'); } var data=payload.data||{}; if(data.published){showAlreadyPublished(data.plaza_url||resolvePlazaUrl({details:{post_id:data.post&&data.post.id}}));return;} showPlazaView('confirm'); }catch(e){ showPlazaView('error'); setStatus(e&&e.message?e.message:'无法检查发布状态',true); } finally{checking=false;} } shareButton&&shareButton.addEventListener('click',async function(){var url=cleanUrl();var title=document.title||'MindSpace';try{if(navigator.share){await navigator.share({title:title,url:url});setStatus('已打开分享');return;}await copyText(url);setStatus('链接已复制');}catch(e){setStatus(e&&e.message?e.message:'分享失败',true);}}); captureButton&&captureButton.addEventListener('click',function(){setStatus('正在生成长图,请稍候');var link=document.createElement('a');link.href=withParam(cleanUrl(),'download','long-image');link.download='';document.body.appendChild(link);link.click();link.remove();}); plazaButton&&plazaButton.addEventListener('click',openPlazaDialog); plazaCancel&&plazaCancel.addEventListener('click',closePlazaDialog); plazaAlreadyClose&&plazaAlreadyClose.addEventListener('click',closePlazaDialog); plazaSuccessClose&&plazaSuccessClose.addEventListener('click',closePlazaDialog); plazaErrorClose&&plazaErrorClose.addEventListener('click',closePlazaDialog); dialog&&dialog.addEventListener('click',function(event){if(event.target===dialog)closePlazaDialog();}); plazaConfirm&&plazaConfirm.addEventListener('click',async function(){ if(publishing)return; var relativePath=workspaceRelativePath(); if(!relativePath){setStatus('无法识别页面路径',true);closePlazaDialog();return;} publishing=true; plazaConfirm.disabled=true; showPlazaView('loading'); try{ var res=await fetch('/api/mindspace/v1/pages/quick-plaza-from-public-html',{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json'},body:JSON.stringify({relative_path:relativePath})}); var payload=await res.json().catch(function(){return{};}); if(!res.ok){ if(res.status===401)throw new Error('请先登录 MindSpace'); var errBody=apiErrorBody(payload); var plazaUrl=resolvePlazaUrl(payload); if(errBody.code==='ALREADY_PUBLISHED'){showAlreadyPublished(plazaUrl);setStatus('该内容已在广场发布',false,true);return;} throw new Error(errBody.message||'发布失败'); } var data=payload.data||{}; var successUrl=data.plaza_url||resolvePlazaUrl({details:{post_id:data.post&&data.post.id}}); showPlazaView('success'); if(plazaSuccessLink&&successUrl){plazaSuccessLink.href=successUrl;plazaSuccessLink.hidden=false;} else if(plazaSuccessLink){plazaSuccessLink.hidden=true;} setStatus('发布成功',false,true); if(successUrl)window.open(successUrl,'_blank','noopener,noreferrer'); }catch(e){ showPlazaView('error'); setStatus(e&&e.message?e.message:'发布失败',true); }finally{publishing=false;plazaConfirm.disabled=false;} }); if(wechatButton&&wechatDialog){ var wechatCancel=wechatDialog.querySelector('[data-action="wechat-cancel"]'); var wechatConfirm=wechatDialog.querySelector('[data-action="wechat-confirm"]'); var wechatSuccessClose=wechatDialog.querySelector('[data-action="wechat-success-close"]'); var wechatErrorClose=wechatDialog.querySelector('[data-action="wechat-error-close"]'); var wechatBlockedClose=wechatDialog.querySelector('[data-action="wechat-blocked-close"]'); var wechatForbiddenClose=wechatDialog.querySelector('[data-action="wechat-forbidden-close"]'); var wechatDraftId=wechatDialog.querySelector('[data-wechat-draft-id]'); var wechatHint=wechatDialog.querySelector('[data-wechat-view="confirm"] [data-wechat-hint]'); var wechatViews={ confirm:wechatDialog.querySelector('[data-wechat-view="confirm"]'), loading:wechatDialog.querySelector('[data-wechat-view="loading"]'), success:wechatDialog.querySelector('[data-wechat-view="success"]'), error:wechatDialog.querySelector('[data-wechat-view="error"]'), blocked:wechatDialog.querySelector('[data-wechat-view="blocked"]'), forbidden:wechatDialog.querySelector('[data-wechat-view="forbidden"]') }; var pushing=false; var wechatChecking=false; function isPageOwner(){return root.getAttribute('data-is-owner')==='true';} function showWechatView(name){Object.keys(wechatViews).forEach(function(key){var view=wechatViews[key];if(view)view.hidden=key!==name;});} function openWechatDialog(){ wechatDialog.hidden=false; if(!isPageOwner()){showWechatView('forbidden');return;} showWechatView('loading'); void refreshWechatDialog(); } function closeWechatDialog(){wechatDialog.hidden=true;showWechatView('confirm');} function setWechatHint(text){if(wechatHint)wechatHint.textContent=text||'';} async function refreshWechatDialog(){ if(wechatChecking)return; var relativePath=workspaceRelativePath(); if(!relativePath){showWechatView('error');setWechatHint('无法识别页面路径');return;} wechatChecking=true; try{ var res=await fetch('/api/mindspace/v1/pages/quick-wechat-draft-from-public-html/status?relative_path='+encodeURIComponent(relativePath),{credentials:'same-origin'}); var payload=await res.json().catch(function(){return{};}); if(!res.ok){ if(res.status===401)throw new Error('请先登录 MindSpace'); var errBody=apiErrorBody(payload); throw new Error(errBody.message||'无法检查公众号草稿状态'); } var data=payload.data||{}; if(!data.configured){showWechatView('blocked');setWechatHint('请先在 M 配置中绑定公众号 AppID 和 AppSecret。');return;} var blockers=(data.validation&&data.validation.blockers)||[]; if(!data.canPush){showWechatView('error');setWechatHint(blockers[0]||'当前页面暂不符合推送要求');return;} setWechatHint(data.pageTitle||'当前页面'); showWechatView('confirm'); }catch(e){ showWechatView('error'); setWechatHint(e&&e.message?e.message:'无法检查公众号草稿状态'); }finally{wechatChecking=false;} } wechatButton.addEventListener('click',openWechatDialog); wechatCancel&&wechatCancel.addEventListener('click',closeWechatDialog); wechatSuccessClose&&wechatSuccessClose.addEventListener('click',closeWechatDialog); wechatErrorClose&&wechatErrorClose.addEventListener('click',closeWechatDialog); wechatBlockedClose&&wechatBlockedClose.addEventListener('click',closeWechatDialog); wechatForbiddenClose&&wechatForbiddenClose.addEventListener('click',closeWechatDialog); wechatDialog.addEventListener('click',function(event){if(event.target===wechatDialog)closeWechatDialog();}); wechatConfirm&&wechatConfirm.addEventListener('click',async function(){ if(pushing)return; var relativePath=workspaceRelativePath(); if(!relativePath){setStatus('无法识别页面路径',true);closeWechatDialog();return;} pushing=true; wechatConfirm.disabled=true; showWechatView('loading'); setWechatHint('正在推送到公众号草稿箱…'); try{ var res=await fetch('/api/mindspace/v1/pages/quick-wechat-draft-from-public-html',{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json'},body:JSON.stringify({relative_path:relativePath})}); var payload=await res.json().catch(function(){return{};}); if(!res.ok){ if(res.status===401)throw new Error('请先登录 MindSpace'); var errBody=apiErrorBody(payload); throw new Error(errBody.message||'推送失败'); } var data=payload.data||{}; showWechatView('success'); if(wechatDraftId){wechatDraftId.textContent=data.draftMediaId?'草稿 media_id:'+data.draftMediaId:'';} setStatus('已推送到公众号草稿箱',false,true); }catch(e){ showWechatView('error'); setWechatHint(e&&e.message?e.message:'推送失败'); }finally{pushing=false;wechatConfirm.disabled=false;} }); } })();`; const PUBLIC_FILE_SHARE_SCRIPT_HASH = crypto .createHash('sha256') .update(PUBLIC_FILE_SHARE_SCRIPT) .digest('base64'); const PUBLIC_FILE_SHARE_WIDGET_BLOCK_PATTERN = /