polyv-live-cli
Version:
CLI tool for managing PolyV live streaming services.
290 lines • 12.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultFilePermissionManager = exports.FilePermissionManager = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
const SECURE_PERMISSIONS = {
OWNER_RW: 0o600,
OWNER_RWX: 0o700
};
class FilePermissionManager {
constructor() {
this.platform = os.platform();
}
supportsUnixPermissions() {
return this.platform !== 'win32';
}
getPermissionInfo(filePath) {
try {
const stats = fs.statSync(filePath);
const mode = stats.mode & parseInt('777', 8);
const isSecure = this.isPermissionSecure(mode, stats.isDirectory());
return {
path: filePath,
mode,
isSecure,
description: this.describePermissions(mode),
warnings: this.generatePermissionWarnings(mode, stats.isDirectory())
};
}
catch (error) {
throw new Error(`Failed to get permission info for ${filePath}: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
isPermissionSecure(mode, isDirectory) {
if (!this.supportsUnixPermissions()) {
return true;
}
const expectedMode = isDirectory ? SECURE_PERMISSIONS.OWNER_RWX : SECURE_PERMISSIONS.OWNER_RW;
return mode === expectedMode;
}
describePermissions(mode) {
if (!this.supportsUnixPermissions()) {
return 'Windows NTFS permissions (managed by system)';
}
const owner = this.formatPermissionGroup((mode >> 6) & 7);
const group = this.formatPermissionGroup((mode >> 3) & 7);
const others = this.formatPermissionGroup(mode & 7);
return `Owner: ${owner}, Group: ${group}, Others: ${others} (${mode.toString(8)})`;
}
formatPermissionGroup(perms) {
const read = (perms & 4) ? 'r' : '-';
const write = (perms & 2) ? 'w' : '-';
const execute = (perms & 1) ? 'x' : '-';
return `${read}${write}${execute}`;
}
generatePermissionWarnings(mode, _isDirectory) {
const warnings = [];
if (!this.supportsUnixPermissions()) {
return warnings;
}
const groupPerms = (mode >> 3) & 7;
if (groupPerms > 0) {
warnings.push('Group has access permissions - configuration file should be accessible only by owner');
}
const otherPerms = mode & 7;
if (otherPerms > 0) {
warnings.push('Others have access permissions - configuration file should be accessible only by owner');
}
if (otherPerms & 4) {
warnings.push('SECURITY RISK: Configuration file is world-readable');
}
if (otherPerms & 2) {
warnings.push('CRITICAL SECURITY RISK: Configuration file is world-writable');
}
return warnings;
}
validatePermissions(filePath) {
try {
if (!fs.existsSync(filePath)) {
return {
isValid: false,
message: `File does not exist: ${filePath}`,
recommendations: ['Create the configuration file first']
};
}
const permissionInfo = this.getPermissionInfo(filePath);
const recommendations = [];
if (!permissionInfo.isSecure) {
if (this.supportsUnixPermissions()) {
recommendations.push(`Run: chmod 600 ${filePath}`);
recommendations.push('Or use: polyv-live-cli config fix-permissions');
}
else {
recommendations.push('Ensure only your user account has access to the configuration file');
recommendations.push('Check Windows file properties and remove other users\' access');
}
}
if (permissionInfo.warnings.length > 0) {
recommendations.push('Review and fix permission warnings above');
}
return {
isValid: permissionInfo.isSecure && permissionInfo.warnings.length === 0,
message: permissionInfo.isSecure
? 'File permissions are secure'
: 'File permissions are not secure - configuration file should only be accessible by owner',
recommendations,
permissionInfo
};
}
catch (error) {
return {
isValid: false,
message: `Failed to validate permissions: ${error instanceof Error ? error.message : 'Unknown error'}`,
recommendations: ['Check if file exists and is accessible']
};
}
}
setSecurePermissions(filePath, isDirectory = false) {
try {
if (!fs.existsSync(filePath)) {
return {
success: false,
message: `Cannot set permissions: File does not exist: ${filePath}`
};
}
const before = this.getPermissionInfo(filePath);
if (!this.supportsUnixPermissions()) {
return {
success: true,
message: 'Windows NTFS permissions are managed by the system. Ensure only your user account has access.',
before,
after: before
};
}
const targetMode = isDirectory ? SECURE_PERMISSIONS.OWNER_RWX : SECURE_PERMISSIONS.OWNER_RW;
fs.chmodSync(filePath, targetMode);
const after = this.getPermissionInfo(filePath);
return {
success: true,
message: `Successfully set secure permissions (${targetMode.toString(8)}) on ${filePath}`,
before,
after
};
}
catch (error) {
return {
success: false,
message: `Failed to set secure permissions: ${error instanceof Error ? error.message : 'Unknown error'}`
};
}
}
ensureSecureDirectory(dirPath) {
try {
if (!fs.existsSync(dirPath)) {
const parentDir = path.dirname(dirPath);
if (!fs.existsSync(parentDir)) {
fs.mkdirSync(parentDir, { recursive: true, mode: SECURE_PERMISSIONS.OWNER_RWX });
}
fs.mkdirSync(dirPath, { mode: SECURE_PERMISSIONS.OWNER_RWX });
}
return this.setSecurePermissions(dirPath, true);
}
catch (error) {
return {
success: false,
message: `Failed to ensure secure directory: ${error instanceof Error ? error.message : 'Unknown error'}`
};
}
}
repairConfigurationFile(filePath) {
try {
const dirPath = path.dirname(filePath);
const dirResult = this.ensureSecureDirectory(dirPath);
if (!dirResult.success) {
return {
success: false,
message: `Failed to secure parent directory: ${dirResult.message}`
};
}
if (fs.existsSync(filePath)) {
return this.setSecurePermissions(filePath, false);
}
else {
return {
success: true,
message: `Parent directory secured. Configuration file ${filePath} will be created with secure permissions.`
};
}
}
catch (error) {
return {
success: false,
message: `Failed to repair configuration file permissions: ${error instanceof Error ? error.message : 'Unknown error'}`
};
}
}
detectPotentialTampering(filePath) {
const reasons = [];
const recommendations = [];
try {
if (!fs.existsSync(filePath)) {
return {
isTampered: false,
reasons: ['File does not exist'],
recommendations: ['Create configuration file if needed']
};
}
const permissionInfo = this.getPermissionInfo(filePath);
if (permissionInfo.warnings.length > 0) {
reasons.push('Insecure file permissions detected');
reasons.push(...permissionInfo.warnings);
recommendations.push('Run permission repair: polyv-live-cli config fix-permissions');
}
if (this.supportsUnixPermissions()) {
const mode = permissionInfo.mode;
if (mode & 2) {
reasons.push('File is world-writable - possible tampering risk');
recommendations.push('Immediately secure the file with: chmod 600 ' + filePath);
}
if (mode & 0o020) {
reasons.push('File is group-writable - possible unauthorized access');
recommendations.push('Remove group write access');
}
}
return {
isTampered: reasons.length > 0,
reasons,
recommendations
};
}
catch (error) {
return {
isTampered: true,
reasons: [`Error checking file permissions: ${error instanceof Error ? error.message : 'Unknown error'}`],
recommendations: ['Verify file exists and is accessible']
};
}
}
getSecurityRecommendations() {
const recommendations = [
'Keep your configuration file in a secure location',
'Regularly backup your configuration file',
'Use the POLYV_MASTER_KEY environment variable for additional security'
];
if (this.supportsUnixPermissions()) {
recommendations.push('Ensure configuration file permissions are set to 600 (owner read/write only)', 'Configuration directory permissions should be 700 (owner access only)', 'Use "ls -la" to check file permissions');
}
else {
recommendations.push('On Windows, ensure only your user account has access to the configuration file', 'Use Windows file properties to review and manage access permissions', 'Consider using Windows folder encryption for additional security');
}
return recommendations;
}
}
exports.FilePermissionManager = FilePermissionManager;
exports.defaultFilePermissionManager = new FilePermissionManager();
//# sourceMappingURL=file-permission-manager.js.map