ghost-plugin-store

Ghost Proxifier 插件商店静态站点

这是 Ghost Proxifier 插件商店的公开静态站点仓库,部署为 https://store.ghostproxifier.com/。它由主仓库(私有)的 examples/store-static/ 同步而来,是插件中心商店页(ghost-store/1)的参考实现——没有框架、没有图片、没有账号、没有购买。

v1/ 是当前部署到 https://store.ghostproxifier.com/v1/ 的全部内容。文中提到的 docs/plugin-sdk/spec-store-bridge.md、src/modules/ui/web/store-bridge.js、.agents/AGENTS.md、src/tests/frontend/ 下的测试文件均指主仓库(私有)里的路径,本仓库不包含它们。

文件 内容
v1/index.html 骨架。CSP 在 <meta> 里:default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'self'。没有内联脚本、没有内联样式
v1/store.js 唯一的脚本,暴露 window.ghostStorePage
v1/store.css 样式,只用系统字体
v1/catalog.json 展示用目录:{v:1, plugins:[{id, version?, minAppVersion?, name:{en, zh?}, description?, homepage?}]}。只用于显示——装什么、装哪个版本永远由 Ghost 自己验过签的注册表决定,与这份文件无关

商店页不在信任链里,所以它只说一句话

托管要求(部署时必须满足)

  1. 独立子域 store.ghostproxifier.com,不能放在 ghostproxifier.com/store/:侧栏广告在 ghostproxifier.com,同一个 origin 会让壳的第一道校验失效。
  2. HTTPS。
  3. 响应头:
    • Content-Security-Policy: frame-ancestors http://127.0.0.1:23551(<meta> 里的 CSP 设不了 frame-ancestors,必须是响应头;这里补的是 frame-ancestors 一条,不放宽 <meta> 已有的 default-src/script-src/style-src/img-src/connect-src)
    • Referrer-Policy: no-referrer
    • X-Content-Type-Options: nosniff
  4. 不设 cookie、不接第三方脚本、不做任何上报(零知识原则)。页面唯一的网络请求是同源的 catalog.json。
  5. catalog.json 与注册表同步:注册表下架或吊销的插件,目录里也要撤掉(撤不撤不影响安全——壳会拒——但会让用户看到一个点了就失败的按钮)。

GitHub Pages 设不了自定义响应头,因此本仓库不启用 Pages。 部署走 Cloudflare Pages 或 Netlify,两者都认根目录下的 _headers 文件(格式相同):

/v1/*
  Content-Security-Policy: frame-ancestors http://127.0.0.1:23551
  Referrer-Policy: no-referrer
  X-Content-Type-Options: nosniff

测试

商店页与商店桥的测试套件(ghost_fe_store_page_test / ghost_fe_store_contract_test,src/tests/frontend/suite_store_page.js / suite_store_contract.js)位于主仓库,不随本站点仓库发布。

同步

本仓库的 v1/ 内容应与主仓库 examples/store-static/v1/ 保持字节一致;改动请先提交到主仓库,再原样同步过来。