remove useless slop stuff

This commit is contained in:
legop3
2026-09-14 02:49:22 -04:00
parent bfdb6555d8
commit 81994f8a56
27 changed files with 301 additions and 233 deletions
@@ -1,5 +1,5 @@
// Configuration System Tests
// Purpose: Verifies strict defaults, immutable revisions, secret handling, legacy import, and administrator safety.
// Purpose: Verifies strict defaults, immutable revisions, secret handling, explicit setup-file import, and administrator safety.
// Scope: Uses isolated temporary databases and never opens the development server's data store.
const test = require('node:test');
const assert = require('node:assert/strict');
@@ -10,7 +10,7 @@ const { defaultConfig, normalizeConfig, assertValidConfig } = require('./validat
const { definitions, rootSchema, secretPaths, featureDefinitions } = require('./definition');
const { getFeatureFlags } = require('./index');
const { createConfigurationDatabase } = require('./database');
const { parseLegacyConfiguration, importLegacyConfiguration } = require('./legacyImporter');
const { parseConfigurationFile, importConfigurationFile } = require('./configurationFileImporter');
const temporaryRoots = [];
@@ -168,7 +168,7 @@ test('administrator storage never exposes hashes or removes the final lockdown a
database.close();
});
test('legacy YAML imports configuration and bcrypt hashes exactly once', () => {
test('an explicitly uploaded YAML file imports configuration and bcrypt hashes exactly once', () => {
const yamlText = `
admins:
- username: owner
@@ -179,14 +179,14 @@ timezone: America/Chicago
media:
whepBaseUrl: http://localhost:8889/video
`;
const parsed = parseLegacyConfiguration(yamlText);
const parsed = parseConfigurationFile(yamlText);
assert.equal(parsed.config.timezone, 'America/Chicago');
assert.equal(parsed.administrators[0].passwordHash, '$2b$10$preservedHash');
const database = createTestDatabase();
const result = importLegacyConfiguration({ text: yamlText, database, dryRun: false });
const result = importConfigurationFile({ text: yamlText, database });
assert.equal(result.administratorCount, 1);
assert.equal(database.findAdministratorForAuthentication('OWNER').passwordHash, '$2b$10$preservedHash');
assert.throws(() => importLegacyConfiguration({ text: yamlText, database }), /cannot replace an initialized installation/);
assert.throws(() => importConfigurationFile({ text: yamlText, database }), /cannot replace an initialized installation/);
database.close();
});
@@ -0,0 +1,67 @@
// Configuration File Importer
// Purpose: Validates one YAML file deliberately uploaded during first-run setup and stores it in the configuration database.
// Scope: This is an explicit setup action only; startup and installation never search for or consume configuration files.
const yaml = require('js-yaml');
const { normalizeConfig, assertValidConfig } = require('./validation');
function normalizeUploadedAdministrator(entry, index) {
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
throw new Error(`Administrator ${index + 1} must be an object.`);
}
const username = String(entry.username || '').trim();
const passwordHash = String(entry.password_hash || '').trim();
if (!username || !passwordHash) {
throw new Error(`Administrator ${index + 1} requires username and password_hash.`);
}
return {
username,
passwordHash,
discordId: String(entry.discord_id || '').trim(),
role: entry.lockdown ? 'lockdown' : 'admin',
};
}
function parseConfigurationFile(text) {
const parsed = yaml.load(String(text || ''));
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error('The configuration file must contain a YAML object.');
}
const administrators = Array.isArray(parsed.admins)
? parsed.admins.map(normalizeUploadedAdministrator)
: [];
const configInput = Object.fromEntries(
Object.entries(parsed).filter(([key]) => key !== 'admins'),
);
const config = normalizeConfig(configInput);
/*
Unknown fields remain in the normalized document so strict schema
validation reports them to the operator instead of silently losing data
from the explicitly selected file.
*/
assertValidConfig(config);
if (!administrators.some((admin) => admin.role === 'lockdown')) {
throw new Error('The configuration file must contain at least one lockdown administrator.');
}
return { config, administrators };
}
function importConfigurationFile({ text, database, actor = 'setup-file-upload', source = 'uploaded-config.yaml' }) {
const result = parseConfigurationFile(text);
const revision = database.importConfigurationFile({
config: result.config,
administrators: result.administrators,
actor,
source,
});
return {
revision,
administratorCount: result.administrators.length,
};
}
module.exports = {
parseConfigurationFile,
importConfigurationFile,
};
+9 -7
View File
@@ -331,8 +331,10 @@ function createConfigurationDatabase({ databasePath = DEFAULT_DATABASE_PATH } =
}));
}
const importLegacyTransaction = db.transaction(({ config, administrators, actor, source }) => {
if (isSetupComplete()) throw new Error('Legacy configuration cannot replace an initialized installation.');
const importConfigurationFileTransaction = db.transaction(({ config, administrators, actor, source }) => {
// A setup upload initializes an empty installation; it is deliberately not
// a general-purpose replacement path for a running server's configuration.
if (isSetupComplete()) throw new Error('A configuration file cannot replace an initialized installation.');
const normalized = assertValidConfig(normalizeConfig(config));
const revision = commitRevisionTransaction(normalized, {
expectedRevision: getActiveConfigurationRecord().revision,
@@ -340,13 +342,13 @@ function createConfigurationDatabase({ databasePath = DEFAULT_DATABASE_PATH } =
source,
});
administrators.forEach((admin) => createAdministratorTransaction(admin, actor, false));
if (!isSetupComplete()) throw new Error('Legacy import must contain at least one lockdown administrator.');
writeAudit(actor, 'legacy-import.completed', { revision, administratorCount: administrators.length, source });
if (!isSetupComplete()) throw new Error('The configuration file must contain at least one lockdown administrator.');
writeAudit(actor, 'setup.configuration-file-imported', { revision, administratorCount: administrators.length, source });
return revision;
});
function importLegacy(payload) {
return importLegacyTransaction(payload);
function importConfigurationFile(payload) {
return importConfigurationFileTransaction(payload);
}
return {
@@ -364,7 +366,7 @@ function createConfigurationDatabase({ databasePath = DEFAULT_DATABASE_PATH } =
countLockdownAdministrators,
isSetupComplete,
listAuditEvents,
importLegacy,
importConfigurationFile,
close: () => db.close(),
};
}
@@ -1,74 +0,0 @@
// Legacy YAML Configuration Importer
// Purpose: Converts one explicitly supplied config.yaml document into the database-backed configuration model.
// Scope: Parses and validates legacy input without becoming a runtime fallback or watcher.
const yaml = require('js-yaml');
const { normalizeConfig, assertValidConfig } = require('./validation');
function normalizeLegacyAdministrator(entry, index) {
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
throw new Error(`Legacy administrator ${index + 1} must be an object.`);
}
const username = String(entry.username || '').trim();
const passwordHash = String(entry.password_hash || '').trim();
if (!username || !passwordHash) {
throw new Error(`Legacy administrator ${index + 1} requires username and password_hash.`);
}
return {
username,
passwordHash,
discordId: String(entry.discord_id || '').trim(),
role: entry.lockdown ? 'lockdown' : 'admin',
};
}
function parseLegacyConfiguration(text) {
const parsed = yaml.load(String(text || ''));
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error('Legacy configuration must contain a YAML object.');
}
const administrators = Array.isArray(parsed.admins)
? parsed.admins.map(normalizeLegacyAdministrator)
: [];
const configInput = Object.fromEntries(
Object.entries(parsed).filter(([key]) => key !== 'admins'),
);
const config = normalizeConfig(configInput);
/*
Unknown fields are retained by normalizeConfig and therefore appear in
Ajv's precise validation errors instead of being silently discarded during
the one-time import.
*/
assertValidConfig(config);
if (!administrators.some((admin) => admin.role === 'lockdown')) {
throw new Error('Legacy configuration must contain at least one lockdown administrator.');
}
return { config, administrators };
}
function importLegacyConfiguration({ text, database, actor = 'legacy-import', source = 'config.yaml', dryRun = false }) {
const result = parseLegacyConfiguration(text);
if (dryRun) {
return {
dryRun: true,
administratorCount: result.administrators.length,
};
}
const revision = database.importLegacy({
config: result.config,
administrators: result.administrators,
actor,
source,
});
return {
dryRun: false,
revision,
administratorCount: result.administrators.length,
};
}
module.exports = {
parseLegacyConfiguration,
importLegacyConfiguration,
};