Commit Graph
186 Commits
Author SHA1 Message Date
MarSeventh 39ae1a7407 feat: configure image resizing in security settings 2026-07-28 11:54:01 +08:00
MarSeventh 4fdd6be188 fix: harden batch delete request handling 2026-07-23 11:43:33 +08:00
MarSeventh b259bb52ea fix: restore batch delete error handling syntax 2026-07-23 11:38:13 +08:00
301bbfa0a9 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-07-23 10:46:13 +08:00
caoyong 65cd72b8b9 feat(manage): add concurrent batch image deletion 2026-07-22 19:59:04 +08:00
MarSeventh 42d1a4f67e chore: update frontend bundle and project assets 2026-07-21 15:53:54 +08:00
MarSeventh cd5f32ba0a feat: add wallpaper toggle and refresh frontend assets 2026-07-21 00:06:37 +08:00
MarSeventh f50a170457 feat: refresh announcement read status 2026-07-15 20:46:52 +08:00
Sebastion bf2c241749 fix(api/fetchRes): mitigate SSRF by validating target URL
The /api/fetchRes proxy endpoint accepted an arbitrary URL from the
request body and passed it directly to fetch(), returning the response
to the caller. Any user with the site auth code could use it to reach
internal services (cloud metadata endpoints, RFC1918 hosts, loopback,
non-http(s) schemes) — a classic CWE-918 SSRF primitive.

The endpoint now:
- rejects non-http(s) schemes
- rejects URLs containing embedded credentials
- rejects hostnames resolving to loopback/private/link-local/CGNAT/
  multicast/reserved ranges, IPv6 ULA/link-local, IPv4-mapped variants
  and well-known cloud metadata hostnames
- follows redirects manually and re-validates each hop (max 5)
2026-07-14 21:37:14 +01:00
MarSeventh e257a40fb9 docs(api): add endpoint file headers 2026-06-15 14:40:11 +08:00
MarSeventh 1ee3eb6a40 feat(worker): cache responses by cache-control 2026-06-15 11:34:49 +08:00
MarSeventh 9b6461a272 feat: support custom upload IP query API 2026-06-14 14:45:00 +08:00
MarSeventh 9fb3cf723a fix: fail closed when security config is unavailable 2026-06-09 19:22:31 +08:00
MarSeventh 6e90b6bf3a fix: clamp session max age before KV write 2026-06-09 18:56:44 +08:00
MarSeventh 6caf75f524 refactor: share metadata channel config lookup 2026-06-03 11:59:22 +08:00
MarSeventh e9cb8cbdff refactor: simplify webdav channel config fields 2026-06-03 11:17:22 +08:00
MarSeventh d061353ddd refactor: rely on config for channel metadata 2026-06-03 10:57:51 +08:00
MarSeventh fed53e807d fix: keep backup metadata persisted only 2026-06-02 23:17:57 +08:00
MarSeventh 4ac7f0ca53 refactor: group metadata utilities 2026-06-02 22:09:45 +08:00
MarSeventh 9b5a3520e1 refactor: trim stored channel metadata 2026-06-02 22:04:47 +08:00
MarSeventh 6a8e4e83bf Unify WebDAV credential resolution 2026-06-02 19:19:43 +08:00
sean908 ceeba86188 fix: strip WebDAV metadata userinfo on move rename 2026-06-02 09:34:52 +00:00
sean908 b9182fdc85 fix: prevent metadata credential leaks 2026-06-02 09:34:52 +00:00
MarSeventh 84246a2210 feat: add upload trend stats 2026-05-25 12:50:04 +08:00
MarSeventh 18b2db1224 fix: WebDAV internal calls use dedicated API Token for authentication
- Add 'internal' token type to API Token system, hidden from the
  security settings token list
- When WebDAV is enabled, auto-create an internal API Token with
  list/upload/delete permissions, stored in WebDAV config
- When WebDAV is disabled, auto-delete the internal token
- WebDAV handler reads the internal token from config and sends it
  as Bearer auth; if missing, creates one on-the-fly as fallback
- Works across both Docker and Cloudflare deployments since the
  token is persisted in KV/D1, not in process memory
2026-05-01 20:27:37 +08:00
MarSeventh 99a8f8d9c5 fix: reduce customer config list load
Return only customer summaries from the list endpoint and lazy-load per-IP files to avoid sending full upload records on every page load.
2026-04-29 16:53:58 +08:00
MarSeventh 7823315b44 fix: reduce manage mutation response payloads 2026-04-29 16:04:36 +08:00
MarSeventh 8a479f75ca fix: prevent cached manage API mutations 2026-04-29 15:59:03 +08:00
MarSeventh 7d01d04547 fix: skip records without timestamps in batch list 2026-04-28 23:25:22 +08:00
MarSeventh 2dbc1ea232 refactor: simplify saving logic of upload config in sysCog API 2026-04-28 21:30:37 +08:00
MarSeventh 392ef53409 refactor: move storage api utils into subdirectory 2026-04-28 17:54:43 +08:00
MarSeventh 9d84a0b34a fix: migrate session storage to manage@ prefix and fix D1 adapter routing
- Change SESSION_PREFIX from 'session@' to 'manage@session@' to prevent
  sessions from appearing in file index and backups
- Add KV expirationTtl for automatic session cleanup on expiry
- Fix D1 adapter: route all manage@ keys to settings table instead of
  files table (fixes blockipList and session storage in wrong table)
- Fix D1 list({ prefix: 'manage@' }) not matching settings table
  (fixes backup not containing settings data)
- Exclude manage@session@ keys from settings backup export
2026-04-28 17:04:41 +08:00
htazq f046b15e6a Keep WebDAV secrets out of file metadata
WebDAV upload records now store only the channel identity and object/public paths. Read, delete, move, and rename operations resolve credentials and headers from the current WebDAV channel config by ChannelName, with a legacy metadata fallback so already-created records remain usable.

Constraint: Preserve existing WebDAV object lifecycle behavior while reducing metadata exposure

Rejected: Keep credentials on every file record | expands exposure through metadata reads, backups, and logs

Confidence: high

Scope-risk: moderate

Directive: Keep WebDAV credentials in upload config/env; do not reintroduce per-file credential metadata

Tested: npm test; node deploy/worker/generate-routes.js; npx wrangler deploy --dry-run --config deploy/worker/wrangler.toml; git diff --check

Not-tested: Live WebDAV provider move/delete/read workflow
2026-04-28 09:42:03 +08:00
htazq 9c7a2b4336 Enable third-party WebDAV storage without new runtime dependencies
Cloudflare Workers and Pages already provide the Fetch/Web APIs needed for WebDAV verbs, so the storage integration uses a small local helper instead of adding a Node-oriented WebDAV client. The channel now participates in upload, read, delete, move, rename, channel listing, and runtime config, with chunked uploads explicitly guarded because WebDAV has no portable server-side compose primitive.

Constraint: Preserve Pages Functions and generated Worker deployment paths
Constraint: No new npm dependency for WebDAV client behavior
Rejected: Add a WebDAV npm client | likely Node API/compatibility and package-lock churn
Rejected: Treat WebDAV as External URL only | not a complete storage channel lifecycle
Confidence: high
Scope-risk: moderate
Directive: WebDAV here is third-party storage; keep it distinct from the built-in /dav server settings
Tested: npm test; node worker/generate-routes.js; npx wrangler deploy --dry-run --config worker/wrangler.toml; git diff --cached --check
Not-tested: Live third-party WebDAV provider credentials; Digest-only WebDAV authentication
2026-04-28 00:05:12 +08:00
MarSeventh b70d0a6f89 fix: remove redundant checkDatabaseConfig from manage middleware
Already executed by parent api/_middleware.js in the chain.
2026-04-25 19:09:58 +08:00
MarSeventh 61f210e0cb feat: 会话安全策略 - 后端支持动态 Secure/MaxAge 配置
- 扩展 getSecurityConfig 和 fetchSecurityConfig 默认值,新增 sessionSecure、userSessionMaxAge、adminSessionMaxAge 字段
- 改造 buildSessionCookie 支持 secure 参数
- createSession 根据 authType 动态读取配置计算 maxAge
- destroySession 读取 sessionSecure 确保清除 Cookie 属性一致
2026-04-21 10:58:54 +08:00
MarSeventh 3f995f6820 fix: sessionCheck adminRequired should also consider password-only config 2026-04-18 16:23:20 +08:00
MarSeventh 876e94b790 refactor: extract rehashIfNeeded to passwordHash.js, deduplicate login rehash logic 2026-04-18 15:35:13 +08:00
MarSeventh 56464b68e4 fix: return explicit authType instead of null when auth is unconfigured
- checkAdmin: return 'admin' when admin auth not configured
- checkUser: return 'user' when authCode not configured
- directoryTree: use authType !== 'admin' to gate user-only checks
2026-04-18 15:28:01 +08:00
MarSeventh 7ef317265f refactor: remove Basic Auth, add /api/auth/adminLogin endpoint
- Remove Basic Auth (verifyBasicAuth, parseBasicAuth) from authCore.js
- Add /api/auth/adminLogin POST endpoint for admin login via JSON body
- Delete legacy /api/manage/check, login, logout (no longer referenced)
- Fix adminConfigured to consider password-only config
2026-04-18 14:49:01 +08:00
MarSeventh 4d2796f54a refactor: unify auth logic into authCore with authScope parameter
- Extract shared authentication logic into utils/auth/authCore.js
- Replace enableBasicAuth/enableAuthCode flags with clear authScope enum (ADMIN/USER/EITHER)
- Move all auth-related files into utils/auth/ subdirectory
- Eliminate duplicated admin auth logic between _middleware.js and dualAuth.js
- Fix: user session no longer grants access to admin-only endpoints
- Fix: dualAuth no longer bypasses authCode when admin is not configured
- Update all 17 import references across the codebase
- Preserve original function signatures (userAuthCheck, dualAuthCheck) for zero caller changes
2026-04-18 13:24:53 +08:00
MarSeventh 636f23375a security: upgrade password hashing to PBKDF2 and fix API token generation
- Replace single-round SHA-256 with PBKDF2 (100k iterations) via Web Crypto API
- Auto-rehash old SHA-256/plaintext passwords to PBKDF2 on successful login
- Add timing-safe comparison to prevent timing attacks
- Replace Math.random() with crypto.getRandomValues() for API token and token ID generation
- Maintain full backward compatibility with existing SHA-256 hashes and plaintext passwords
2026-04-18 00:45:04 +08:00
MarSeventh 61181b54ed refactor: move auth endpoints to /api/auth/ subdirectory
- login.js -> auth/login.js (/api/auth/login)
- logout.js -> auth/logout.js (/api/auth/logout)
- sessionCheck.js -> auth/sessionCheck.js (/api/auth/sessionCheck)
- resetAuth.js -> auth/resetAuth.js (/api/auth/resetAuth)
- Update import paths in moved files
2026-04-17 23:46:24 +08:00
MarSeventh b3f8a03ec3 feat: add /api/resetAuth endpoint for password recovery
Allows resetting all auth config when locked out:
- Requires RESET_KEY environment variable to be set
- GET /api/resetAuth?key=YOUR_RESET_KEY
- Clears security config from database (falls back to env vars)
- Destroys all active sessions
2026-04-17 23:37:11 +08:00
MarSeventh 298897edf4 fix: use ?? for config fallback, add clear password support and auth-required check
- Fix getSecurityConfig: use ?? instead of || so empty string is preserved
- Handle _clear flag to explicitly remove passwords
- Clear adminUsername together with adminPassword on _clear
- sessionCheck now returns adminRequired/userRequired fields
- Return 200 instead of 401 from sessionCheck for frontend to decide
2026-04-17 23:32:27 +08:00
MarSeventh 62c5aa0eed feat: session-based auth with password hashing
- Add passwordHash.js: SHA-256 + salt hashing with plaintext backward compatibility
- Add sessionManager.js: HttpOnly cookie sessions with separate admin_session/user_session
- Add sessionCheck.js: session validation endpoint for frontend route guards
- Add logout.js: session destruction endpoint with authType support
- Update login.js: return user_session cookie on successful login
- Update check.js: return admin_session cookie on successful admin auth
- Update _middleware.js: check admin_session before Basic Auth, remove WWW-Authenticate header
- Update security.js: hash passwords on save, mask in GET, clear sessions on password change
- Update dualAuth.js/userAuth.js: use verifyPassword and session validation
2026-04-17 23:11:45 +08:00
MarSeventh 115635ff5e feat: add i18n English labels for page config API 2026-03-28 22:06:46 +08:00
MarSeventh e7e62b1485 Feat:细化Token权限,支持设置管理权限 2026-03-10 18:59:03 +08:00
MarSeventh 2628de051d feat: 添加 API Token 过期时间后端支持
- 新增 tokenExpiration.js 工具模块(过期判定、自动删除过滤)
- apiTokens.js 支持 expiresAt/autoDelete 字段的创建、更新、自动清理
- 新增 getTokenData 导出函数
- tokenValidator.js 增加过期检查逻辑
2026-03-10 10:52:01 +08:00
MarSeventh bc6e385cb6 提升索引重建在不同网络环境下的鲁棒性 2026-03-05 12:26:56 +08:00