84 lines
2.9 KiB
JavaScript
84 lines
2.9 KiB
JavaScript
import { readFileSync } from 'node:fs';
|
|
|
|
function text(name, fallback) {
|
|
const value = process.env[name];
|
|
return value === undefined || value === '' ? fallback : value;
|
|
}
|
|
|
|
function secret(name, fileName) {
|
|
const direct = process.env[name];
|
|
if (direct) {
|
|
return direct;
|
|
}
|
|
|
|
const path = process.env[fileName];
|
|
if (!path) {
|
|
throw new Error(`${name} or ${fileName} is required`);
|
|
}
|
|
return readFileSync(path, 'utf8').trim();
|
|
}
|
|
|
|
function clientSecrets(variableName) {
|
|
const entries = text(variableName, '')
|
|
.split(',')
|
|
.map((entry) => entry.trim())
|
|
.filter(Boolean);
|
|
if (entries.length === 0) {
|
|
throw new Error(`${variableName} is required`);
|
|
}
|
|
|
|
const result = Object.create(null);
|
|
for (const entry of entries) {
|
|
const separator = entry.indexOf('=');
|
|
const client = entry.slice(0, separator);
|
|
const path = entry.slice(separator + 1);
|
|
if (separator < 1 || !/^[a-z0-9][a-z0-9_-]{1,31}$/.test(client) || !path) {
|
|
throw new Error(`Invalid ${variableName} client entry: ${entry}`);
|
|
}
|
|
const value = readFileSync(path, 'utf8').trim();
|
|
if (value.length < 32) {
|
|
throw new Error(`${variableName} secret for ${client} must be at least 32 characters`);
|
|
}
|
|
if (result[client]) {
|
|
throw new Error(`Duplicate ${variableName} client: ${client}`);
|
|
}
|
|
result[client] = value;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export function loadConfig() {
|
|
const webhookSecret = secret('GITEA_WEBHOOK_SECRET', 'GITEA_WEBHOOK_SECRET_FILE');
|
|
const adminSecret = secret('IMAGE_ADMIN_SECRET', 'IMAGE_ADMIN_SECRET_FILE');
|
|
if (webhookSecret.length < 32 || adminSecret.length < 32) {
|
|
throw new Error('Webhook and admin secrets must be at least 32 characters');
|
|
}
|
|
|
|
const allowedBranches = text('IMAGE_ALLOWED_BRANCHES', 'master')
|
|
.split(',')
|
|
.map((branch) => branch.trim())
|
|
.filter(Boolean);
|
|
|
|
return {
|
|
port: Number(text('PORT', '8081')),
|
|
repositoryPath: text('IMAGE_REPOSITORY_PATH', '/data/image'),
|
|
remoteUrl: text('IMAGE_REMOTE_URL', 'https://gitea.hided.net/devsam/image.git'),
|
|
repositoryFullName: text('IMAGE_REPOSITORY_FULL_NAME', 'devsam/image'),
|
|
defaultBranch: text('IMAGE_DEFAULT_BRANCH', 'master'),
|
|
allowedBranches,
|
|
statePath: text('IMAGE_STATE_PATH', '/var/lib/image-hook/state.json'),
|
|
publicBases: text('IMAGE_PUBLIC_BASES', 'https://sam.hided.net/image,https://sam-image.hided.net')
|
|
.split(',')
|
|
.map((base) => base.trim().replace(/\/$/, ''))
|
|
.filter(Boolean),
|
|
webhookSecret,
|
|
adminSecret,
|
|
syncClientSecrets: clientSecrets('IMAGE_SYNC_CLIENT_SECRET_FILES'),
|
|
uploadClientSecrets: clientSecrets('IMAGE_UPLOAD_CLIENT_SECRET_FILES'),
|
|
maxBodyBytes: Number(text('MAX_BODY_BYTES', '1048576')),
|
|
maxUploadBytes: Number(text('MAX_UPLOAD_BYTES', '51200')),
|
|
uploadRoot: text('IMAGE_UPLOAD_ROOT', '/var/lib/image-hook/uploads'),
|
|
uploadStatePath: text('IMAGE_UPLOAD_STATE_PATH', '/var/lib/image-hook/upload-state.json'),
|
|
};
|
|
}
|