All files / src/business permissions.ts

0% Statements 0/38
100% Branches 1/1
100% Functions 1/1
0% Lines 0/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71                                                                                                                                             
/**
 * User Permissions Logic
 *
 * Centralized business logic for generating user permissions based on role and plan.
 */
 
import type { SubscriptionPlan } from "./plan";
 
export type UserRole = "admin" | "user" | "viewer" | null;
 
/**
 * Plan-based feature permissions
 */
const PLAN_PERMISSIONS: Record<SubscriptionPlan, string[]> = {
	free: ["snapshot:create:5/day"],
	pro: ["snapshot:*", "api:webhooks"],
	team: ["snapshot:*", "api:webhooks", "api:advanced-analytics", "team:collaboration"],
	enterprise: [
		"snapshot:*",
		"api:*",
		"team:*",
		"sso:enabled",
		"audit:enabled",
		"compliance:enabled",
		"support:priority",
	],
};
 
/**
 * Generate permissions array based on user role and subscription plan
 * @param userId - User ID (for future audit/cache purposes)
 * @param role - User's role (admin, user, viewer)
 * @param plan - User's subscription plan
 */
export async function getUserPermissions(_userId: string, role: UserRole, plan: SubscriptionPlan): Promise<string[]> {
	const permissions: string[] = [];
 
	// Role-based permissions
	if (role === "admin") {
		permissions.push("admin:read", "admin:write", "admin:delete", "org:manage", "user:manage");
	}
	if (role === "user" || role === "admin") {
		permissions.push("snapshot:create", "snapshot:read", "snapshot:update", "snapshot:delete");
	}
	if (role === "viewer" || role === "user" || role === "admin") {
		permissions.push("snapshot:view", "report:view");
	}
 
	// Plan-based permissions
	permissions.push(...(PLAN_PERMISSIONS[plan] || PLAN_PERMISSIONS.free));
 
	return permissions;
}
 
/**
 * Check if permissions include a specific permission (supports wildcards)
 */
export function hasPermission(permissions: string[], requiredPerm: string): boolean {
	// Admin wildcard
	if (permissions.includes("*")) {
		return true;
	}
	// Exact match
	if (permissions.includes(requiredPerm)) {
		return true;
	}
	// Wildcard pattern match (e.g., "snapshot:*" matches "snapshot:create")
	const [resource] = requiredPerm.split(":");
	return permissions.includes(`${resource}:*`);
}