fix(files): authorize downloads for wrapper apps via signed tokens - #528
Open
xiaojueshi wants to merge 1 commit into
Open
fix(files): authorize downloads for wrapper apps via signed tokens#528xiaojueshi wants to merge 1 commit into
xiaojueshi wants to merge 1 commit into
Conversation
Wrapper apps (e.g. Pake) replay file-download links through their own HTTP client, which does not carry the page's Basic credentials, so every download behind PI_WEB_PASSWORD fails with 401. Add a short-lived signed download token (bound to the path, 5-min TTL) issued by a new endpoint and verified in the proxy, so downloads pass without Basic auth while all other API requests stay password-protected. - app/api/auth/download-token/route.ts: issue tokens for files inside allowed roots (symlinks re-checked); Basic auth guarded by the proxy. - proxy.ts: download requests with a valid token skip the Basic check; invalid tokens get an explicit 403. - components/FileExplorer.tsx: prefetch the token on hover and write it into the download href before Pake's capture-phase click interception; attach a readable name via the download attribute only for extensions Pake hijacks. - lib/download-auth.ts + lib/pake-download-extensions.ts with unit tests. Verified with curl against a dev server: token download returns 200 with full bytes, missing/invalid/expired tokens are rejected, basic-auth downloads regress clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
目的
Pi Web 可以开启
PI_WEB_PASSWORD(HTTP Basic 认证)。当页面被桌面封装应用(如 Pake)包裹时,文件浏览器的下载会持续报
401 Unauthorized:封装应用会用自己的 HTTP 客户端重放下载链接,而该客户端不携带 webview 已缓存的 Basic 凭据。
实现方式
用一段绑定文件路径、短时有效的签名令牌,替代缺失的 Basic 凭据,仅作用于
文件下载这一个请求:
app/api/auth/download-token(新增):在通过常规的 allowed-roots 校验(并对符号链接二次校验)后,为文件签发 5 分钟的 HMAC 签名令牌。端点本身
仍受 Basic 认证保护。
proxy.ts:匹配/api/files/**?type=download且携带有效令牌的请求跳过Basic 检查;令牌无效或过期则显式返回
403。其余所有/api/*请求保持密码保护不变。
components/FileExplorer.tsx:悬停(hover)时预取令牌并写入下载链接的href——因为封装应用在 capture 阶段拦截点击,任何 React 点击处理器都来不及再取令牌。仅对封装应用会接管的扩展名附加可读文件名(
download属性)。lib/download-auth.ts/lib/pake-download-extensions.ts(新增)及单元测试:覆盖签名/校验、过期、防篡改,以及镜像封装应用可下载扩展名清单的边界。
带来的变化
PI_WEB_PASSWORD时,封装应用内下载恢复正常。Content-Disposition文件名。type=download形态生效,不能用于其他 API。签名密钥为进程内随机值(不落盘),除非显式设置
PI_WEB_DOWNLOAD_SECRET。测试
lib/download-auth.test.mjs(7 项)、lib/pake-download-extensions.test.mjs(4 项)。200且字节数完整;缺失/无效/过期/篡改路径的令牌被拒绝(
401/403);Basic 认证下载回归通过。