71 lines
2.3 KiB
JavaScript
71 lines
2.3 KiB
JavaScript
import { readFileSync } from 'node:fs';
|
|
import { dirname, resolve } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const projectRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
|
|
/**
|
|
* Loads `.env` into process.env without a dependency. Node's own `--env-file` needs 20.6+;
|
|
* parsing it here keeps the runbook a plain `npm start` on any Node 18+.
|
|
* Real environment variables always win, so a container/CI can override the file.
|
|
*/
|
|
function loadDotEnv() {
|
|
let raw;
|
|
try {
|
|
raw = readFileSync(resolve(projectRoot, '.env'), 'utf8');
|
|
} catch {
|
|
return;
|
|
}
|
|
|
|
for (const line of raw.split(/\r?\n/)) {
|
|
const trimmed = line.trim();
|
|
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
|
|
const eq = trimmed.indexOf('=');
|
|
if (eq === -1) continue;
|
|
|
|
const key = trimmed.slice(0, eq).trim();
|
|
let value = trimmed.slice(eq + 1).trim();
|
|
if (value.length >= 2 && ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'")))) {
|
|
value = value.slice(1, -1);
|
|
}
|
|
|
|
if (!(key in process.env)) process.env[key] = value;
|
|
}
|
|
}
|
|
|
|
loadDotEnv();
|
|
|
|
const botToken = (process.env.TELEGRAM_BOT_TOKEN ?? '').trim();
|
|
if (!botToken) {
|
|
console.error('FATAL: TELEGRAM_BOT_TOKEN is not set. Copy .env.example to .env and paste the token from @BotFather.');
|
|
process.exit(1);
|
|
}
|
|
|
|
const chatIds = (process.env.TELEGRAM_CHAT_IDS ?? '')
|
|
.split(',')
|
|
.map((id) => id.trim())
|
|
.filter(Boolean);
|
|
|
|
// The API key is mandatory, with no opt-out: an OTP relay that anyone can POST to is an open
|
|
// message cannon pointed at the test group's phones. Fail to start rather than listen unprotected.
|
|
const apiKey = (process.env.API_KEY ?? '').trim();
|
|
if (!apiKey) {
|
|
console.error('FATAL: API_KEY is not set. Choose any shared secret, put it in .env, and configure the same value on the caller.');
|
|
process.exit(1);
|
|
}
|
|
|
|
if (apiKey.length < 16) {
|
|
console.error(`FATAL: API_KEY is too short (${apiKey.length} chars). Use at least 16 — e.g. output of: node -e "console.log(require('crypto').randomBytes(24).toString('hex'))"`);
|
|
process.exit(1);
|
|
}
|
|
|
|
export const config = {
|
|
botToken,
|
|
chatIds,
|
|
apiKey,
|
|
host: (process.env.HOST ?? '127.0.0.1').trim(),
|
|
port: Number(process.env.PORT ?? 5010),
|
|
redactCodeInLogs: (process.env.REDACT_CODE_IN_LOGS ?? 'false').toLowerCase() === 'true',
|
|
};
|