Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions deploy/miniapp-market/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,19 @@ curl -fsS https://market.openbitfun.com/miniapp/api/v1/config
curl -fsS https://market.openbitfun.com/miniapp/ >/dev/null
```

生产 `/config` 应返回 `"webSubmissionsEnabled":false`。此开关关闭时,Web
投稿写请求由后端拒绝,网页仅保留“我的投稿”历史;BitFun Desktop 的 Bearer
投稿和 Web 管理员审核继续可用。未来重新开放网页投稿时,必须先完成对应安全
回归,再显式修改 root-only `market.env` 并仅 recreate 市场容器。
环境变量缺失时后端也默认关闭,但生产 `market.env` 应显式保留
`MARKET_WEB_SUBMISSIONS_ENABLED=false`,避免后续运维人员误判当前策略。

再用浏览器人工检查:

- `/miniapp/` 能加载,刷新子页面不会 404;
- `MARKET_PUBLIC_BROWSE=false` 时匿名目录按预期关闭;
- `MARKET_WEB_SUBMISSIONS_ENABLED=false` 时投稿/更新/撤回按钮不可见,直接访问
`/miniapp/submit` 提示改用 BitFun Desktop,“我的投稿”仍可读取;
- OAuth 已配置时,GitHub 登录 callback 正常;
- 与本次改动有关的浏览、下载、投稿、审核、安装或更新流程正常;
- Relay、New API 和官网仍可用,且它们的容器/vhost 没被重启或改写。
Expand Down
2 changes: 2 additions & 0 deletions deploy/miniapp-market/market.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
MARKET_PUBLIC_BASE_URL=https://market.openbitfun.com/miniapp
MARKET_PUBLIC_BROWSE=false
# Keep browser-based submission writes disabled. BitFun Desktop uses Bearer auth and remains enabled.
MARKET_WEB_SUBMISSIONS_ENABLED=false
MARKET_GITHUB_CLIENT_ID=
MARKET_GITHUB_CLIENT_SECRET=
MARKET_SESSION_SECRET=replace-with-at-least-32-random-bytes
Expand Down
6 changes: 6 additions & 0 deletions src/apps/miniapp-market-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,14 @@ cargo run -p bitfun-miniapp-market-server
| `MARKET_SESSION_SECRET` | 会话签名 secret,生产至少 24 字符并应使用强随机值 |
| `MARKET_ADMIN_GITHUB_IDS` | 逗号分隔的 GitHub 数字 ID |
| `MARKET_PUBLIC_BROWSE` | 是否向匿名用户开放目录 |
| `MARKET_WEB_SUBMISSIONS_ENABLED` | 是否允许 Web Cookie 会话投稿;默认及生产为 `false`,Desktop Bearer 投稿不受影响 |
| `RUST_LOG` | 英文 JSON 日志过滤器 |

未设置 `MARKET_WEB_SUBMISSIONS_ENABLED` 时服务按 `false` 处理;它与
`MARKET_PUBLIC_BROWSE` 相互独立。生产修改该值需要仅 recreate 市场容器,并通过
`GET /miniapp/api/v1/config` 核对实际的 `webSubmissionsEnabled`,不能只根据
env 文件内容判断已经生效。

固定生产 OAuth callback 是:

`https://market.openbitfun.com/miniapp/api/v1/auth/github/callback`
Expand Down
20 changes: 20 additions & 0 deletions src/crates/services/miniapp-market-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,26 @@
- GitHub token 只用于读取公开 `{id,login,avatar_url}`,随后丢弃,不能下发给
Web 或桌面客户端。
- 管理员身份每次请求按 GitHub 数字 ID 计算,不能依赖客户端声明。
- `MARKET_WEB_SUBMISSIONS_ENABLED=false` 时,所有投稿写路由会在读取请求体前
拒绝 Web Cookie 会话;Desktop Bearer 投稿、投稿历史读取和 Web 管理员审核
保持可用。UI 隐藏不是这一边界的替代品。

## 当前投稿入口与鉴权矩阵

生产默认 `MARKET_WEB_SUBMISSIONS_ENABLED=false`。该开关只控制普通用户的投稿
写入,不控制目录、评分收藏、只读投稿历史或管理员审核:

| 请求面 | Web Cookie | Desktop Bearer | 开关关闭时 |
| --- | --- | --- | --- |
| 公开目录、详情、下载 | 可选登录 | 可选登录 | 不变 |
| 评分与收藏 | 登录并校验 CSRF | 登录 | 不变 |
| `GET /submissions`、`GET /submissions/{id}` | 登录 | 登录 | 保持可读 |
| `POST /submissions`、包/截图 PUT/DELETE、submit、withdraw | 登录并校验 CSRF | 登录 | Web 在读取 body 前返回 `403 web_submissions_disabled`;Desktop 保持可写 |
| `/admin/*` 审核和下架 | 管理员登录并校验 CSRF | 管理员登录 | 不受该开关影响 |

匿名或无效凭据的投稿写请求仍先返回 `401 unauthorized`。未来重新开放 Web 投稿时,
必须显式设置环境变量、recreate 容器,并重新验证 CSRF、上传大小、恶意包拒绝和
所有投稿状态转换;不得仅修改前端显示条件。

## 本地验证

Expand Down
1 change: 1 addition & 0 deletions src/crates/services/miniapp-market-service/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ mod tests {
session_secret: "test-session-secret-at-least-24".to_string(),
admin_github_ids: HashSet::from([24753352]),
public_browse: false,
web_submissions_enabled: false,
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/crates/services/miniapp-market-service/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct MarketConfig {
pub session_secret: String,
pub admin_github_ids: HashSet<i64>,
pub public_browse: bool,
pub web_submissions_enabled: bool,
}

impl MarketConfig {
Expand Down Expand Up @@ -57,6 +58,9 @@ impl MarketConfig {
let public_browse = env::var("MARKET_PUBLIC_BROWSE")
.map(|value| matches!(value.as_str(), "1" | "true" | "TRUE" | "yes"))
.unwrap_or(true);
let web_submissions_enabled = env::var("MARKET_WEB_SUBMISSIONS_ENABLED")
.map(|value| matches!(value.as_str(), "1" | "true" | "TRUE" | "yes"))
.unwrap_or(false);

Ok(Self {
bind,
Expand All @@ -69,6 +73,7 @@ impl MarketConfig {
session_secret,
admin_github_ids,
public_browse,
web_submissions_enabled,
})
}

Expand Down
1 change: 1 addition & 0 deletions src/crates/services/miniapp-market-service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ mod tests {
session_secret: "test-session-secret-at-least-24".to_string(),
admin_github_ids: [24753352].into_iter().collect(),
public_browse: true,
web_submissions_enabled: false,
};
tokio::fs::create_dir_all(&config.web_dir).await.unwrap();
tokio::fs::write(config.web_dir.join("index.html"), "<html></html>")
Expand Down
Loading