This commit is contained in:
@@ -2,11 +2,18 @@ import { posix } from 'node:path';
|
||||
import { gameOfServer, relDestForKind, type ArtifactKind } from '../config.js';
|
||||
|
||||
export const BANK_CONFIG_FILE = 'electric_cherry_bank.cfg';
|
||||
export const MODERATION_CONFIG_FILE = 'electric_cherry_moderation.cfg';
|
||||
export const PRIVATE_CONFIG_FILES = [BANK_CONFIG_FILE, MODERATION_CONFIG_FILE] as const;
|
||||
|
||||
export function isPrivateConfigPath(path: string, game = 't5'): boolean {
|
||||
return (
|
||||
posix.normalize(path.replaceAll('\\', '/')) ===
|
||||
posix.join(relDestForKind('config', game), BANK_CONFIG_FILE)
|
||||
// Moderation bootstrap has one fixed runtime location, even when shared
|
||||
// artifact destinations were customized for an older installation.
|
||||
if (posix.normalize(path.replaceAll('\\', '/')) === `configs/${MODERATION_CONFIG_FILE}`)
|
||||
return true;
|
||||
return PRIVATE_CONFIG_FILES.some(
|
||||
(filename) =>
|
||||
posix.normalize(path.replaceAll('\\', '/')) ===
|
||||
posix.join(relDestForKind('config', game), filename)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,26 +30,31 @@ export function isPrivateConfigTarget(server: string, kind: string, path: string
|
||||
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.'
|
||||
'Private bank configuration and moderation 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;
|
||||
return PRIVATE_CONFIG_FILES.some(
|
||||
(filename) => posix.basename(path.replaceAll('\\', '/')).toLowerCase() === filename
|
||||
);
|
||||
}
|
||||
|
||||
// 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)
|
||||
PRIVATE_CONFIG_FILES.some(
|
||||
(filename) => posix.normalize(path.replaceAll('\\', '/')) === filename
|
||||
) || isPrivateConfigPath(path)
|
||||
);
|
||||
}
|
||||
|
||||
/** Credential injection uses bank.configPath, never a shared file's path field. */
|
||||
/** Credential injection uses a private 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.');
|
||||
super(
|
||||
'Private bank configuration and moderation configuration cannot be read or changed by file operations.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ export function createScript(input: CreateScriptInput): {
|
||||
if (!targetRelPath) throw new ScriptError('target rel path is required', 'path-empty');
|
||||
if (isReservedConfigFilename(targetRelPath))
|
||||
throw new ScriptError(
|
||||
'electric_cherry_bank.cfg is reserved for instance credentials.',
|
||||
`${targetRelPath} is reserved for instance credentials.`,
|
||||
'path-reserved'
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user