Initial commit with translated description
This commit is contained in:
141
scripts/config.js
Normal file
141
scripts/config.js
Normal file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
// Config file locations
|
||||
const PRIMARY_ENV_PATH = path.join(os.homedir(), '.config', 'imap-smtp-email', '.env');
|
||||
const FALLBACK_ENV_PATH = path.resolve(__dirname, '../.env');
|
||||
|
||||
// Find the .env file: primary location first, then fallback
|
||||
function findEnvPath() {
|
||||
if (fs.existsSync(PRIMARY_ENV_PATH)) return PRIMARY_ENV_PATH;
|
||||
if (fs.existsSync(FALLBACK_ENV_PATH)) return FALLBACK_ENV_PATH;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse and strip --account <name> from process.argv
|
||||
// After this, process.argv[2] is always the command
|
||||
function parseAccountFromArgv(argv) {
|
||||
const args = argv.slice(2);
|
||||
const idx = args.indexOf('--account');
|
||||
if (idx !== -1 && idx + 1 < args.length) {
|
||||
const name = args[idx + 1];
|
||||
args.splice(idx, 2);
|
||||
return { accountName: name, remainingArgs: args };
|
||||
}
|
||||
return { accountName: null, remainingArgs: args };
|
||||
}
|
||||
|
||||
// Build config object from environment variables
|
||||
// prefix: uppercase account name (e.g., 'WORK') or null for default
|
||||
function buildConfig(env, prefix) {
|
||||
const p = prefix ? `${prefix}_` : '';
|
||||
|
||||
// Account existence check for named accounts
|
||||
if (prefix && !env[`${p}IMAP_HOST`]) {
|
||||
console.error(`Error: Account "${prefix.toLowerCase()}" not found in config. Check ~/.config/imap-smtp-email/.env`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return {
|
||||
imap: {
|
||||
host: env[`${p}IMAP_HOST`] || '127.0.0.1',
|
||||
port: parseInt(env[`${p}IMAP_PORT`]) || 1143,
|
||||
user: env[`${p}IMAP_USER`],
|
||||
pass: env[`${p}IMAP_PASS`],
|
||||
tls: env[`${p}IMAP_TLS`] === 'true',
|
||||
rejectUnauthorized: env[`${p}IMAP_REJECT_UNAUTHORIZED`] !== 'false',
|
||||
mailbox: env[`${p}IMAP_MAILBOX`] || 'INBOX',
|
||||
},
|
||||
smtp: {
|
||||
host: env[`${p}SMTP_HOST`],
|
||||
port: parseInt(env[`${p}SMTP_PORT`]) || 587,
|
||||
user: env[`${p}SMTP_USER`],
|
||||
pass: env[`${p}SMTP_PASS`],
|
||||
secure: env[`${p}SMTP_SECURE`] === 'true',
|
||||
from: env[`${p}SMTP_FROM`] || env[`${p}SMTP_USER`],
|
||||
rejectUnauthorized: env[`${p}SMTP_REJECT_UNAUTHORIZED`] !== 'false',
|
||||
},
|
||||
allowedReadDirs: (env.ALLOWED_READ_DIRS || '').split(',').map(d => d.trim()).filter(Boolean),
|
||||
allowedWriteDirs: (env.ALLOWED_WRITE_DIRS || '').split(',').map(d => d.trim()).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
// List all configured accounts from .env file
|
||||
// Returns { accounts: Array, configPath: String|null }
|
||||
function listAccounts() {
|
||||
const envPath = findEnvPath();
|
||||
if (!envPath) {
|
||||
return { accounts: [], configPath: null };
|
||||
}
|
||||
|
||||
// Parse the env file fresh to get all account prefixes
|
||||
const dotenvResult = dotenv.config({ path: envPath });
|
||||
const env = dotenvResult.parsed || {};
|
||||
const accounts = [];
|
||||
const seen = new Set();
|
||||
|
||||
// Check for default account (no prefix)
|
||||
if (env.IMAP_HOST) {
|
||||
accounts.push(createAccountObject(env, '', 'default'));
|
||||
seen.add('default');
|
||||
}
|
||||
|
||||
// Scan for named accounts (pattern: XXX_IMAP_HOST)
|
||||
for (const key of Object.keys(env)) {
|
||||
const match = key.match(/^([A-Z0-9]+)_IMAP_HOST$/);
|
||||
if (match) {
|
||||
const prefix = match[1];
|
||||
const name = prefix.toLowerCase();
|
||||
if (!seen.has(name)) {
|
||||
accounts.push(createAccountObject(env, prefix + '_', name));
|
||||
seen.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { accounts, configPath: envPath };
|
||||
}
|
||||
|
||||
// Create an account object from env variables
|
||||
function createAccountObject(env, prefix, name) {
|
||||
const p = prefix;
|
||||
return {
|
||||
name,
|
||||
email: env[`${p}IMAP_USER`] || env[`${p}SMTP_FROM`] || '-',
|
||||
imapHost: env[`${p}IMAP_HOST`] || '-',
|
||||
smtpHost: env[`${p}SMTP_HOST`] || '-',
|
||||
isComplete: isAccountComplete(env, prefix)
|
||||
};
|
||||
}
|
||||
|
||||
// Check if an account has all required configuration
|
||||
function isAccountComplete(env, prefix) {
|
||||
const p = prefix;
|
||||
return !!(
|
||||
env[`${p}IMAP_HOST`] &&
|
||||
env[`${p}IMAP_USER`] &&
|
||||
env[`${p}IMAP_PASS`] &&
|
||||
env[`${p}SMTP_HOST`]
|
||||
);
|
||||
}
|
||||
|
||||
// --- Module initialization ---
|
||||
const envPath = findEnvPath();
|
||||
if (envPath) {
|
||||
dotenv.config({ path: envPath });
|
||||
}
|
||||
|
||||
const { accountName, remainingArgs } = parseAccountFromArgv(process.argv);
|
||||
const prefix = accountName ? accountName.toUpperCase() : null;
|
||||
|
||||
// Strip --account from process.argv so callers see command at argv[2]
|
||||
process.argv = [process.argv[0], process.argv[1], ...remainingArgs];
|
||||
|
||||
const config = buildConfig(process.env, prefix);
|
||||
|
||||
module.exports = config;
|
||||
module.exports.listAccounts = listAccounts;
|
||||
Reference in New Issue
Block a user