feat: add enterprise licensing and S3 storage backend

Add the enterprise package with Ed25519 license key validation and
feature gating. Enterprise code lives in the public repo under a
proprietary license (Cal.com/PostHog model), protected legally, not
by code hiding.

Implement S3-compatible storage backend as the first enterprise
feature. The file-storage module now delegates to either local
filesystem or S3 based on STORAGE_MODE env var. Works with AWS S3,
Cloudflare R2, DigitalOcean Spaces, MinIO, and any S3-compatible
provider. Workspace files remain local (ephemeral processing).

New env vars: STORAGE_MODE, S3_BUCKET, S3_REGION, S3_ENDPOINT,
S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_FORCE_PATH_STYLE,
S3_PREFIX, SNAPOTTER_LICENSE_KEY.

Tested against MinIO: 10 S3 integration tests + 82 existing tests
pass with zero regressions.
This commit is contained in:
SnapOtter
2026-06-06 20:17:49 +08:00
parent 06d1822491
commit 3b84fab765
15 changed files with 658 additions and 27 deletions
+21
View File
@@ -98,6 +98,20 @@ if (!env.COOKIE_SECRET) {
await initAnalytics();
// Enterprise features (license-gated)
let enterpriseLicense: { org: string; plan: string } | null = null;
try {
const { initEnterprise } = await import("@snapotter/enterprise");
const result = initEnterprise(env.SNAPOTTER_LICENSE_KEY || undefined);
if (result.valid && result.license) {
enterpriseLicense = result.license;
} else if (env.SNAPOTTER_LICENSE_KEY) {
console.warn("[WARN] Invalid or expired enterprise license key");
}
} catch {
// Enterprise package not available
}
// Mark any jobs left in processing/queued from a previous unclean shutdown
recoverStaleJobs();
@@ -278,6 +292,9 @@ app.get("/api/v1/admin/health", async (request, reply) => {
database: dbOk ? "ok" : "error",
queue: { active: 0, pending: 0 },
ai: { gpu: isGpuAvailable(), dispatcher: getDispatcherStatus() },
enterprise: enterpriseLicense
? { active: true, org: enterpriseLicense.org, plan: enterpriseLicense.plan }
: { active: false },
};
});
@@ -319,6 +336,10 @@ try {
`[INFO] Rate limit: ${env.RATE_LIMIT_PER_MIN > 0 ? `${env.RATE_LIMIT_PER_MIN}/min` : "disabled"}`,
`[INFO] Upload limit: ${env.MAX_UPLOAD_SIZE_MB > 0 ? `${env.MAX_UPLOAD_SIZE_MB} MB` : "unlimited"}`,
`[INFO] Trust proxy: ${env.TRUST_PROXY}`,
`[INFO] Storage: ${env.STORAGE_MODE}${env.STORAGE_MODE === "s3" ? ` (${env.S3_BUCKET})` : ""}`,
enterpriseLicense
? `[INFO] Enterprise license: ${enterpriseLicense.org} (${enterpriseLicense.plan})`
: "[INFO] Edition: Community",
].join("\n"),
);
} catch (err) {