fix: fail closed on invalid launch inputs
ci/woodpecker/pr/ci Pipeline was successful

This commit is contained in:
be-coder-06
2026-08-12 20:41:24 -05:00
parent 216cd72226
commit 55f2ec3dbc
10 changed files with 507 additions and 35 deletions
+1
View File
@@ -3,6 +3,7 @@ export {
DEFAULT_LOCAL_CONFIG,
DEFAULT_STANDALONE_CONFIG,
DEFAULT_FEDERATED_CONFIG,
MosaicConfigEnvironmentError,
loadConfig,
validateConfig,
detectFromEnv,
@@ -0,0 +1,72 @@
import { readFileSync } from 'node:fs';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { MosaicConfigEnvironmentError as PublicMosaicConfigEnvironmentError } from '@mosaicstack/config';
import { detectFromEnv } from './mosaic-config.js';
interface TypedSelectionFailure {
readonly name: string;
readonly code: string;
}
describe('#1182 fail closed — a wrong answer must not be read as no answer', () => {
const originalEnv = process.env;
it('exports the typed storage-tier refusal from the public @mosaicstack/config entry point', () => {
expect(new PublicMosaicConfigEnvironmentError()).toBeInstanceOf(Error);
});
beforeEach(() => {
process.env = { ...originalEnv };
delete process.env['DATABASE_URL'];
delete process.env['VALKEY_URL'];
delete process.env['MOSAIC_STORAGE_TIER'];
});
afterEach(() => {
process.env = originalEnv;
});
it('FL-08 rejects an invalid explicit MOSAIC_STORAGE_TIER before local PGlite selection', () => {
process.env['MOSAIC_STORAGE_TIER'] = 'federatd';
let pgliteSelectionCount = 0;
let failure: unknown;
try {
const config = detectFromEnv();
if (config.storage.type === 'pglite') {
pgliteSelectionCount += 1;
}
} catch (error: unknown) {
failure = error;
}
expect
.soft(failure, 'invalid explicit storage tier must produce a typed selection failure')
.toMatchObject({
name: 'MosaicConfigEnvironmentError',
code: 'invalid_storage_tier',
} satisfies TypedSelectionFailure);
expect(
pgliteSelectionCount,
'invalid explicit storage tier must fail before local PGlite is selected',
).toBe(0);
});
it.each([undefined, ''])('preserves the local default for true absence: %j', (tier) => {
if (tier === undefined) delete process.env['MOSAIC_STORAGE_TIER'];
else process.env['MOSAIC_STORAGE_TIER'] = tier;
const config = detectFromEnv();
expect(config.tier).toBe('local');
expect(config.storage.type).toBe('pglite');
});
it('anti-drift: storage selection validates a non-empty tier before the local default', () => {
const source = readFileSync(new URL('./mosaic-config.ts', import.meta.url), 'utf8');
expect(
/if \(tier !== undefined && tier !== ''[^]*throw new [A-Za-z]+Error/.test(source),
'closed storage enums must reject invalid explicit input before DEFAULT_LOCAL_CONFIG',
).toBe(true);
});
});
+14
View File
@@ -20,6 +20,16 @@ export interface MosaicConfig {
memory: MemoryConfigRef;
}
/** Typed startup refusal for an invalid explicit storage-tier selection. */
export class MosaicConfigEnvironmentError extends Error {
readonly code = 'invalid_storage_tier' as const;
constructor() {
super('Invalid MOSAIC_STORAGE_TIER; expected "local", "standalone", or "federated".');
this.name = 'MosaicConfigEnvironmentError';
}
}
/* ------------------------------------------------------------------ */
/* Defaults */
/* ------------------------------------------------------------------ */
@@ -126,6 +136,10 @@ export function validateConfig(raw: unknown): MosaicConfig {
export function detectFromEnv(): MosaicConfig {
const tier = process.env['MOSAIC_STORAGE_TIER'];
if (tier !== undefined && tier !== '' && !VALID_TIERS.has(tier)) {
throw new MosaicConfigEnvironmentError();
}
if (tier === 'federated') {
if (process.env['DATABASE_URL']) {
return {