Agent-Profile: https://agent-kanban.dev/agents/a318237412dd8b98
8.8 KiB
ZPan v2.6 Release Notes
What's New
ZPan v2.6 introduces ZPan Pro — a paid tier that unlocks operator-grade features for people running ZPan as a platform for others. Free self-hosted personal use remains supported, with the operator-grade gates noted below.
v2.6 also adds the Pro quota store. This is a scoped storage purchase and redemption flow for Pro operators; it does not move generic Pro activation into ZPan. Cloud remains the merchant of record and owns Stripe, subscriptions, membership redemption, and payment operations.
ZPan Pro
Cloud Account Binding
Connect your ZPan instance to a ZPan Cloud account using a device-code pairing flow — no callback URL required, so it works on home labs, internal networks, and NATted VPS hosts.
- Go to Settings → Billing and click Connect to ZPan Cloud.
- ZPan displays a short code. Visit
cloud.zpan.space/pairon any device, sign in, and enter the code. - ZPan detects confirmation and shows your plan within seconds.
Entitlement Certificates
Pro status is verified locally using an Ed25519-signed certificate fetched from cloud.zpan.space every 6 hours. No network call happens per request — the certificate is cached in your database. ZPan tolerates up to 24 hours of cloud downtime before feature gates fall back to Free.
White-Label (first Pro feature)
Customize the look of your ZPan instance:
- Upload a custom logo and favicon
- Set a custom wordmark text (replaces "ZPan" in titles and copy)
- Hide the "Powered by ZPan" footer badge
Manage in Settings → Branding.
Pro Quota Store
The quota store lets a Pro instance operator sell or grant extra storage to terminal users on that ZPan instance.
Direction and Ownership
- Cloud is merchant of record in v2.6. Stripe Checkout, Stripe webhooks, Cloud order state, and storage-code inventory run through ZPan Cloud.
- The ZPan operator defines the package catalog per instance. Admins create packages in ZPan with name, description, bytes, price, currency, active state, and sort order.
- Terminal buyers do not need Cloud accounts. ZPan signs purchase and redemption sessions; Cloud uses those sessions for checkout or storage-code redemption.
- Quota grants are permanent additive credits in v2.6. For finite base quotas, effective quota is base org quota plus active grants. Editing the admin base quota does not erase paid or redeemed grants. The existing
0base quota sentinel still means unlimited. - Generic Pro activation stays Cloud-owned. Subscription purchase, membership redemption, and Pro entitlement activation remain in the Cloud dashboard.
Admin Setup
- Bind the ZPan instance to a Pro Cloud entitlement.
- Open the admin quota store settings.
- Enable the store.
- Set the Cloud base URL, the public ZPan instance URL, and the webhook signing secret.
- Confirm the generated callback URL is publicly reachable over HTTPS:
/api/quota-store/webhooks/cloud. - Create active packages and confirm their Cloud sync status is
synced.
The user-facing store remains unavailable while disabled or while the webhook signing secret is missing.
Buyer Flow
- A terminal user opens Store from the quota meter.
- The user chooses a personal or team target org.
- Checkout calls ZPan, then Cloud creates Stripe Checkout from the signed package snapshot.
- After Stripe marks the Cloud order paid, Cloud delivers the quota grant to ZPan through a signed callback.
- ZPan records the delivery idempotently, adds one immutable quota grant, and refreshes effective quota, quota meter, and grant history.
Users who previously hit quota can retry confirm/upload while the draft still exists after the grant arrives.
Storage-Code Redemption
Storage-code redemption is separate from Cloud membership redemption:
- Users redeem storage codes in ZPan Store against a selected personal or team org.
- Cloud validates the storage code and sends quota delivery through the same signed callback path.
- Membership redemption remains on Cloud and does not share this flow.
Verification Notes
The merged implementation covers:
- Pro gating for quota store admin and self-service APIs
- Package validation, Cloud catalog sync, and Cloud sync error surfacing
- Target org access checks for checkout and redemption
- Anonymous Cloud checkout handoff from signed ZPan storage sessions
- Stripe-paid Cloud order delivery through signed callback
- Duplicate Cloud delivery returning success without a second grant
- Bad Cloud webhook signatures returning
401 - Admin base quota edits preserving paid grants in effective quota
- Upload confirm quota checks using base quota plus active grants
- Storage-code redemption using storage-code endpoints, not membership redemption
Manual preview evidence was captured in the quota-store UI work:
- Open admin quota-store settings, enable the store, configure Cloud base URL, public instance URL, and webhook signing secret, then create an active package and confirm Cloud sync status.
- Screenshot:
/tmp/zpan-quota-store-preview/admin-package-store.png
- Screenshot:
- Open the terminal-user Store from the quota meter without a Cloud account, select a personal or team target org, and confirm active packages render.
- Screenshot:
/tmp/zpan-quota-store-preview/user-store-packages.png
- Screenshot:
- Start checkout and confirm ZPan opens the Cloud/Stripe checkout URL from the signed storage session.
- Screenshot:
/tmp/zpan-quota-store-preview/checkout-launch.png
- Screenshot:
- Redeem a storage code for the selected org and confirm grant history plus quota meter refresh.
- Screenshot:
/tmp/zpan-quota-store-preview/redemption-quota-update.png
- Screenshot:
Backend verification covered duplicate Cloud delivery not double-granting quota, bad webhook signatures returning 401, and admin base quota edits preserving paid grants.
Retroactive Pro Gates
Three features from earlier versions have moved to Pro in v2.6. These affect only operators running ZPan as a platform for unknown third parties.
Open Registration (open_registration)
Registration modes closed and invite-only remain Free. Open registration (anyone can sign up without an invite) requires Pro.
If you were using open registration mode, set up a Pro license before upgrading or your instance will fall back to invite-only.
Team Count > 1 Extra Team (teams_unlimited)
Free instances may have 1 personal workspace + up to 1 team. Creating a 2nd team requires Pro. Existing teams are never deleted; the gate only prevents creating new ones beyond the limit.
Storage Backend Count > 3 (storages_unlimited)
Free instances may configure up to 3 storage backends. Adding a 4th storage requires Pro.
Feature Gate Overview
| Feature | Free | Pro |
|---|---|---|
| All v2.0–v2.5 features | ✅ | ✅ |
| Open registration mode | — | ✅ |
| Teams beyond 1 extra team | — | ✅ |
| Unlimited storages | Up to 3 | ✅ |
| White-label branding | — | ✅ |
| Quota store | — | ✅ |
Upgrading
- Pull the latest image:
docker pull ghcr.io/saltbo/zpan:latest - Restart your container — migrations run automatically.
- If you use open registration mode, bind a Pro license before restarting (see above).
- Optional: go to Settings → Billing to connect your cloud account and activate Pro.
- Optional for Pro operators: enable Quota Store only after configuring a public HTTPS callback URL and webhook signing secret.
For Cloudflare Workers deployments, trigger the Deploy to Cloudflare Workers workflow from your fork's Actions tab.
Known Issues
None at release time.
Changelog Summary
feat(licensing): Ed25519 entitlement verification layer (server/licensing/)feat(licensing): Cloud account binding via device-code flowfeat(licensing): 6h background entitlement refresh with manual "Refresh now" buttonfeat(ui): Settings → Billing page (bound / unbound states)feat(ui):<ProBadge />and<UpgradeHint />frontend primitivesfeat(branding): White-label settings page (logo, favicon, wordmark, footer toggle)feat(quota-store): Pro-gated admin package catalog and store settings with Cloud sync statusfeat(quota-store): Terminal-user storage checkout, target org selection, storage-code redemption, and grant historyfeat(quota-store): Signed Cloud delivery callback with idempotent quota grantsfeat(quota-store): Effective quota now includes permanent additive storage grantsfeat(gates): Open registration gated behindopen_registrationPro featurefeat(gates): Team creation blocked after 1 extra team for Free (teams_unlimitedrequired for the 3rd org)feat(gates): Storage creation blocked at 3 for Free (storages_unlimitedrequired for the 4th storage)