Files
electric-cherry/src/lib/server/fleet/private-config.ts
T

55 lines
2.1 KiB
TypeScript

import { posix } from 'node:path';
import { gameOfServer, relDestForKind, type ArtifactKind } from '../config.js';
export const BANK_CONFIG_FILE = 'electric_cherry_bank.cfg';
export function isPrivateConfigPath(path: string, game = 't5'): boolean {
return (
posix.normalize(path.replaceAll('\\', '/')) ===
posix.join(relDestForKind('config', game), BANK_CONFIG_FILE)
);
}
export function isPrivateConfigTarget(server: string, kind: string, path: string): boolean {
if (kind !== 'script' && kind !== 'config' && kind !== 'baseline' && kind !== 'plugin')
throw new Error('Invalid artifact kind');
const game = gameOfServer(server);
return isPrivateConfigPath(
posix.join(relDestForKind(kind, game), path.replaceAll('\\', '/')),
game
);
}
export function assertPublicFileTarget(server: string, kind: ArtifactKind, path: string): void {
if (isPrivateConfigTarget(server, kind, path))
throw new Error(
'Private bank configuration cannot be captured or changed by a file campaign.'
);
}
export function isReservedConfigFilename(path: string): boolean {
return posix.basename(path.replaceAll('\\', '/')).toLowerCase() === BANK_CONFIG_FILE;
}
// Legacy campaign evidence omits the kind and stores the path relative to its destination.
export function isPrivateConfigEvidencePath(path: string): boolean {
return (
posix.normalize(path.replaceAll('\\', '/')) === BANK_CONFIG_FILE ||
isPrivateConfigPath(path)
);
}
/** Credential injection uses bank.configPath, never a shared file's path field. */
export class PrivateFileOperationError extends Error {
constructor() {
super('Private bank configuration cannot be read or changed by file operations.');
}
}
export function assertPublicFilePayload(value: unknown): void {
if (!value || typeof value !== 'object') return;
if ('path' in value && typeof value.path === 'string' && isPrivateConfigPath(value.path))
throw new PrivateFileOperationError();
for (const item of Object.values(value)) assertPublicFilePayload(item);
}