Use metadata-aware personal workspace detection across org repositories and UI, generate personal/team slugs with the new default random rules, and remove user-managed team slug fields.
Encode WebDAV path segments consistently so Finder follows workspace names such as Ambor's Space via %27 instead of XML-escaped apostrophes.
* feat(admin): separate billing configuration
Add dedicated storage egress and downloader credit billing contracts, usecases, RPC wrappers, drawers, generated client updates, and coverage.
Agent-Profile: https://agent-kanban.dev/agents/2673e70e0085f4e0
* fix(billing): preserve not found ordering
Check storage and downloader existence before quota_store gating in dedicated billing usecases, and cover enabled missing-resource requests at usecase and route levels.
Agent-Profile: https://agent-kanban.dev/agents/2673e70e0085f4e0
---------
Co-authored-by: Jordan Park <jordan-park@mails.agent-kanban.dev>
* feat: make forcePathStyle configurable per storage
Previously hardcoded to true, which breaks S3-compatible backends that require
virtual-hosted-style addressing (e.g. Alibaba Cloud OSS). Now configurable via
admin storage settings with a toggle switch, defaulting to true for backwards
compatibility.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* test: cover storage force path style
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: saltbo <saltbo@foxmail.com>
Clears all 23 open CodeQL alerts:
- actions/missing-workflow-permissions (19, medium): add a top-level
least-privilege `permissions: contents: read` to ci.yml and the 7
deploy workflows. The one CI job that needs `packages: write` already
declares its own block; all deploys authenticate via static secrets
(no OIDC / id-token, no repo writes), so read is sufficient.
- js/insecure-randomness (1, high): `genPassword()` built share
passwords with Math.random(); switch to crypto.getRandomValues() over
the same unambiguous alphabet (length/charset/uniqueness preserved).
- js/incomplete-url-substring-sanitization (2, high): two test fetch
stubs routed on `String(url).includes('api.github.com')`; tighten to
`new URL(url).hostname === 'api.github.com'` — precise and no longer
flagged.
- js/stack-trace-exposure (1, medium): the E2E S3 mock echoed
error.message in 500 responses; log server-side and return a generic
body instead.
Verified: typecheck green; share-dialog/changelog/system.integration
tests pass.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Create SECURITY.md for security policy
Added a security policy document outlining supported versions and vulnerability reporting.
Signed-off-by: Jasper Van <saltbo@foxmail.com>
* docs: fill in real SECURITY.md policy for ZPan
Replace the GitHub default template (placeholder 5.x/4.x versions and
boilerplate) with an actual policy: supported 2.x versions, private
vulnerability reporting via GitHub Security Advisories, and response-time
expectations.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: saltbo <saltbo@foxmail.com>
* docs: express supported versions relative to latest release
Avoid pinning a concrete minor (2.7.x) that goes stale on every release.
ZPan ships fixes forward on a single release train and does not backport,
so 'latest release only' is both accurate and zero-maintenance.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: saltbo <saltbo@foxmail.com>
---------
Signed-off-by: Jasper Van <saltbo@foxmail.com>
Signed-off-by: saltbo <saltbo@foxmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve Dependabot alert #36 (esbuild <= 0.24.2, medium): "esbuild enables
any website to send any requests to the development server and read the
response."
The vulnerable esbuild 0.18.20 was dragged in transitively by drizzle-kit's
deprecated @esbuild-kit/esm-loader → @esbuild-kit/core-utils (both "Merged
into tsx"). drizzle-kit 0.31.10 — the latest — still declares the legacy
loader even though it now uses tsx, so bumping drizzle-kit can't fix it.
Scoped pnpm override forces only @esbuild-kit/core-utils>esbuild to 0.25.12
(already resolved in the tree via drizzle-kit's own esbuild ^0.25.4), so it
dedups to a single version and leaves vite/tsup/vitest esbuild untouched.
Verified: drizzle-kit `db:generate` loads the TS config + full schema and
exits 0 with no spurious migrations; typecheck and production build green.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve Dependabot security alerts:
- nodemailer (high): the message-level `raw` option bypassed
disableFileAccess/disableUrlAccess (arbitrary file read + SSRF). Our
email gateway only sends `html` over an SMTP transport (no `raw`, no
remote attachment fetching, no OAuth2/proxy), so neither the vuln nor
the 9.0 TLS-cert-validation breaking change affects our usage.
- undici (3 high / 2 med / 2 low): the override pinned undici at 7.24.8
(a leftover dedup pin from the pnpm migration, not a real constraint).
Bump it to 7.28.0; consumers (jsdom/vitest/better-auth/miniflare/
wrangler) all accept ^7, so it dedups to a single patched version.
Verified: typecheck, 4347 unit/integration + 59 CF Workers tests, and a
production vite build all green.
Supersedes #458.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
No callers remain after select('public') was removed in #456 — the
public-bucket flow is gone, so the gateway method, its port declaration
and its tests are dead code.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>