mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat: add enterprise Phase 1-4 feature flags and new permissions
This commit is contained in:
@@ -20,6 +20,9 @@ const ROLE_PERMISSIONS: Record<Role, Permission[]> = {
|
|||||||
"features:manage",
|
"features:manage",
|
||||||
"system:health",
|
"system:health",
|
||||||
"audit:read",
|
"audit:read",
|
||||||
|
"compliance:manage",
|
||||||
|
"webhooks:manage",
|
||||||
|
"security:manage",
|
||||||
],
|
],
|
||||||
editor: [
|
editor: [
|
||||||
"tools:use",
|
"tools:use",
|
||||||
|
|||||||
@@ -211,6 +211,9 @@ export async function ensureBuiltinRoles(): Promise<void> {
|
|||||||
"features:manage",
|
"features:manage",
|
||||||
"system:health",
|
"system:health",
|
||||||
"audit:read",
|
"audit:read",
|
||||||
|
"compliance:manage",
|
||||||
|
"webhooks:manage",
|
||||||
|
"security:manage",
|
||||||
],
|
],
|
||||||
isBuiltin: true,
|
isBuiltin: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
ENTERPRISE_FEATURES,
|
ENTERPRISE_FEATURES,
|
||||||
type EnterpriseFeature,
|
type EnterpriseFeature,
|
||||||
type LicensePayload,
|
type LicensePayload,
|
||||||
|
PLAN_FEATURES,
|
||||||
validateLicense,
|
validateLicense,
|
||||||
} from "./license.js";
|
} from "./license.js";
|
||||||
|
|
||||||
@@ -31,4 +32,4 @@ export type S3StorageModule = typeof import("./storage-s3.js");
|
|||||||
export async function loadS3Storage(): Promise<S3StorageModule> {
|
export async function loadS3Storage(): Promise<S3StorageModule> {
|
||||||
return import("./storage-s3.js");
|
return import("./storage-s3.js");
|
||||||
}
|
}
|
||||||
export { ENTERPRISE_FEATURES, type EnterpriseFeature, type LicensePayload };
|
export { ENTERPRISE_FEATURES, PLAN_FEATURES, type EnterpriseFeature, type LicensePayload };
|
||||||
|
|||||||
@@ -13,12 +13,31 @@ export const ENTERPRISE_FEATURES = [
|
|||||||
"audit_export",
|
"audit_export",
|
||||||
"mfa",
|
"mfa",
|
||||||
"per_tool_permissions",
|
"per_tool_permissions",
|
||||||
|
"siem_forwarding",
|
||||||
|
"tamper_resistant_audit",
|
||||||
|
"legal_hold",
|
||||||
|
"gdpr_lifecycle",
|
||||||
|
"team_retention_overrides",
|
||||||
|
"sso_enforcement",
|
||||||
|
"ip_allowlist",
|
||||||
|
"config_export_import",
|
||||||
|
"upgrade_management",
|
||||||
|
"admin_alerts",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type EnterpriseFeature = (typeof ENTERPRISE_FEATURES)[number];
|
export type EnterpriseFeature = (typeof ENTERPRISE_FEATURES)[number];
|
||||||
|
|
||||||
export const PLAN_FEATURES: Record<string, readonly EnterpriseFeature[]> = {
|
export const PLAN_FEATURES: Record<string, readonly EnterpriseFeature[]> = {
|
||||||
team: ["saml_sso", "s3_storage", "multi_tenancy"],
|
team: [
|
||||||
|
"saml_sso",
|
||||||
|
"s3_storage",
|
||||||
|
"multi_tenancy",
|
||||||
|
"audit_export",
|
||||||
|
"siem_forwarding",
|
||||||
|
"sso_enforcement",
|
||||||
|
"upgrade_management",
|
||||||
|
"admin_alerts",
|
||||||
|
],
|
||||||
enterprise: ENTERPRISE_FEATURES,
|
enterprise: ENTERPRISE_FEATURES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ export type Permission =
|
|||||||
| "teams:manage"
|
| "teams:manage"
|
||||||
| "features:manage"
|
| "features:manage"
|
||||||
| "system:health"
|
| "system:health"
|
||||||
| "audit:read";
|
| "audit:read"
|
||||||
|
| "compliance:manage"
|
||||||
|
| "webhooks:manage"
|
||||||
|
| "security:manage";
|
||||||
|
|
||||||
export type Role = "admin" | "editor" | "user";
|
export type Role = "admin" | "editor" | "user";
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { ENTERPRISE_FEATURES, PLAN_FEATURES } from "@snapotter/enterprise";
|
||||||
|
|
||||||
|
describe("enterprise feature flags", () => {
|
||||||
|
it("includes all Phase 1 flags", () => {
|
||||||
|
expect(ENTERPRISE_FEATURES).toContain("siem_forwarding");
|
||||||
|
expect(ENTERPRISE_FEATURES).toContain("tamper_resistant_audit");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("includes all Phase 2-4 flags", () => {
|
||||||
|
expect(ENTERPRISE_FEATURES).toContain("legal_hold");
|
||||||
|
expect(ENTERPRISE_FEATURES).toContain("gdpr_lifecycle");
|
||||||
|
expect(ENTERPRISE_FEATURES).toContain("admin_alerts");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("team plan includes operational features", () => {
|
||||||
|
expect(PLAN_FEATURES.team).toContain("siem_forwarding");
|
||||||
|
expect(PLAN_FEATURES.team).toContain("audit_export");
|
||||||
|
expect(PLAN_FEATURES.team).toContain("upgrade_management");
|
||||||
|
expect(PLAN_FEATURES.team).toContain("admin_alerts");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("team plan does NOT include compliance features", () => {
|
||||||
|
expect(PLAN_FEATURES.team).not.toContain("tamper_resistant_audit");
|
||||||
|
expect(PLAN_FEATURES.team).not.toContain("legal_hold");
|
||||||
|
expect(PLAN_FEATURES.team).not.toContain("gdpr_lifecycle");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("enterprise plan includes everything", () => {
|
||||||
|
for (const feature of ENTERPRISE_FEATURES) {
|
||||||
|
expect(PLAN_FEATURES.enterprise).toContain(feature);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("has exactly 18 features total", () => {
|
||||||
|
expect(ENTERPRISE_FEATURES).toHaveLength(18);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user