Fix: Use JSON config files for ESM compatibility
- Replace @simpleworkjs/conf with simple custom loader - Use JSON config files (base, development, production, secrets) - Add config.js with ESM-compatible deep merge - Support env var overrides for critical settings - Auth disabled in dev mode via development.json
This commit is contained in:
36
conf/base.js
36
conf/base.js
@@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* Base configuration - shared across all environments
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
server: {
|
|
||||||
port: 3000,
|
|
||||||
host: '0.0.0.0'
|
|
||||||
},
|
|
||||||
|
|
||||||
gateway: {
|
|
||||||
url: 'http://127.0.0.1:18789',
|
|
||||||
token: 'a41984619a5f4b9bf9148ab6eb4abca53eb796d046cbbec5'
|
|
||||||
},
|
|
||||||
|
|
||||||
session: {
|
|
||||||
secret: 'change-me-in-production',
|
|
||||||
maxAge: 24 * 60 * 60 * 1000 // 24 hours
|
|
||||||
},
|
|
||||||
|
|
||||||
auth: {
|
|
||||||
disabled: false,
|
|
||||||
ldap: {
|
|
||||||
enabled: false,
|
|
||||||
url: 'ldap://localhost:389',
|
|
||||||
baseDN: 'ou=users,dc=example,dc=com',
|
|
||||||
bindDN: '',
|
|
||||||
bindPassword: '',
|
|
||||||
searchFilter: '(uid={{username}})'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
data: {
|
|
||||||
dir: './data'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
27
conf/base.json
Normal file
27
conf/base.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"port": 3000,
|
||||||
|
"host": "0.0.0.0"
|
||||||
|
},
|
||||||
|
"gateway": {
|
||||||
|
"url": "http://127.0.0.1:18789"
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"secret": "change-me-in-production",
|
||||||
|
"maxAge": 86400000
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"disabled": false,
|
||||||
|
"ldap": {
|
||||||
|
"enabled": false,
|
||||||
|
"url": "ldap://localhost:389",
|
||||||
|
"baseDN": "ou=users,dc=example,dc=com",
|
||||||
|
"bindDN": "",
|
||||||
|
"bindPassword": "",
|
||||||
|
"searchFilter": "(uid={{username}})"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"dir": "./data"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* Development environment configuration
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
auth: {
|
|
||||||
disabled: true, // Skip auth in dev
|
|
||||||
ldap: {
|
|
||||||
enabled: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
server: {
|
|
||||||
// Vite runs on 5173, proxy from there
|
|
||||||
}
|
|
||||||
};
|
|
||||||
8
conf/development.json
Normal file
8
conf/development.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"auth": {
|
||||||
|
"disabled": true,
|
||||||
|
"ldap": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* Production environment configuration
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
server: {
|
|
||||||
// Use PORT env var if set, otherwise default
|
|
||||||
port: parseInt(process.env.PORT) || 3000
|
|
||||||
},
|
|
||||||
|
|
||||||
session: {
|
|
||||||
// Should be set via secrets.js in production
|
|
||||||
secret: process.env.SESSION_SECRET || 'CHANGE-ME-NOW'
|
|
||||||
},
|
|
||||||
|
|
||||||
auth: {
|
|
||||||
disabled: false,
|
|
||||||
ldap: {
|
|
||||||
enabled: process.env.LDAP_ENABLED === 'true'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
11
conf/production.json
Normal file
11
conf/production.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"port": 3000
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"secret": "CHANGE-ME-NOW"
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"disabled": false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Example secrets file
|
|
||||||
*
|
|
||||||
* Copy this to secrets.js and fill in your actual values
|
|
||||||
* secrets.js is ignored by git
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
gateway: {
|
|
||||||
// Your OpenClaw gateway token
|
|
||||||
token: 'your-gateway-token-here'
|
|
||||||
},
|
|
||||||
|
|
||||||
session: {
|
|
||||||
// Random string for session signing
|
|
||||||
secret: 'generate-a-random-string-here'
|
|
||||||
},
|
|
||||||
|
|
||||||
auth: {
|
|
||||||
ldap: {
|
|
||||||
// LDAP bind credentials (if needed for search)
|
|
||||||
bindDN: 'cn=admin,dc=example,dc=com',
|
|
||||||
bindPassword: 'ldap-admin-password'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
14
conf/secrets.example.json
Normal file
14
conf/secrets.example.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"gateway": {
|
||||||
|
"token": "your-gateway-token-here"
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"secret": "generate-a-random-string-here"
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"ldap": {
|
||||||
|
"bindDN": "cn=admin,dc=example,dc=com",
|
||||||
|
"bindPassword": "ldap-admin-password"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
conf/secrets.json
Normal file
14
conf/secrets.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"gateway": {
|
||||||
|
"token": "a41984619a5f4b9bf9148ab6eb4abca53eb796d046cbbec5"
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"secret": "dev-session-secret-change-in-production"
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"ldap": {
|
||||||
|
"bindDN": "",
|
||||||
|
"bindPassword": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
package-lock.json
generated
19
package-lock.json
generated
@@ -8,7 +8,6 @@
|
|||||||
"name": "openclaw-webui",
|
"name": "openclaw-webui",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@simpleworkjs/conf": "^1.0.0",
|
|
||||||
"eventsource": "^2.0.2",
|
"eventsource": "^2.0.2",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
@@ -871,18 +870,6 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@simpleworkjs/conf": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@simpleworkjs/conf/-/conf-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-p1dQAELW0oUBRpDoz260TYw18IMI/Y11xYAb17P1MEPjsTAUB0LWE/6ZeA2VQmpU/LXoRnDysg0G/oASGILyUA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"extend": "^3.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||||
@@ -1448,12 +1435,6 @@
|
|||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/extend": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/extsprintf": {
|
"node_modules/extsprintf": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz",
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@simpleworkjs/conf": "^1.0.0",
|
|
||||||
"eventsource": "^2.0.2",
|
"eventsource": "^2.0.2",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
|
|||||||
75
server/config.js
Normal file
75
server/config.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* Simple ESM-compatible configuration loader
|
||||||
|
* Loads JSON files: base.json -> environment.json -> secrets.json
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readFileSync, existsSync } from 'fs';
|
||||||
|
import { join, dirname } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
function deepMerge(target, source) {
|
||||||
|
const result = { ...target };
|
||||||
|
for (const key of Object.keys(source)) {
|
||||||
|
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
||||||
|
result[key] = deepMerge(result[key] || {}, source[key]);
|
||||||
|
} else {
|
||||||
|
result[key] = source[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadJsonFile(filename) {
|
||||||
|
const path = join(__dirname, '..', 'conf', filename);
|
||||||
|
if (!existsSync(path)) return {};
|
||||||
|
try {
|
||||||
|
return JSON.parse(readFileSync(path, 'utf-8'));
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(`Warning: Failed to load ${filename}:`, err.message);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load configuration
|
||||||
|
const environment = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
|
const base = loadJsonFile('base.json');
|
||||||
|
const envConfig = loadJsonFile(`${environment}.json`);
|
||||||
|
const secrets = loadJsonFile('secrets.json');
|
||||||
|
|
||||||
|
// Merge all configs
|
||||||
|
const config = deepMerge(deepMerge(base, envConfig), secrets);
|
||||||
|
|
||||||
|
// Add environment info
|
||||||
|
config.environment = environment;
|
||||||
|
|
||||||
|
// Allow env var overrides for critical settings
|
||||||
|
if (process.env.PORT) {
|
||||||
|
config.server = config.server || {};
|
||||||
|
config.server.port = parseInt(process.env.PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.OPENCLAW_GATEWAY) {
|
||||||
|
config.gateway = config.gateway || {};
|
||||||
|
config.gateway.url = process.env.OPENCLAW_GATEWAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.OPENCLAW_TOKEN) {
|
||||||
|
config.gateway = config.gateway || {};
|
||||||
|
config.gateway.token = process.env.OPENCLAW_TOKEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.SESSION_SECRET) {
|
||||||
|
config.session = config.session || {};
|
||||||
|
config.session.secret = process.env.SESSION_SECRET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.LDAP_ENABLED === 'true') {
|
||||||
|
config.auth = config.auth || {};
|
||||||
|
config.auth.ldap = config.auth.ldap || {};
|
||||||
|
config.auth.ldap.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config;
|
||||||
@@ -18,11 +18,11 @@ import { join, dirname } from 'path';
|
|||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import ldap from 'ldapjs';
|
import ldap from 'ldapjs';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import conf from '@simpleworkjs/conf';
|
import conf from './config.js';
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
// Configuration via @simpleworkjs/conf
|
// Configuration
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
port: conf.server?.port || 3000,
|
port: conf.server?.port || 3000,
|
||||||
gatewayUrl: conf.gateway?.url || 'http://127.0.0.1:18789',
|
gatewayUrl: conf.gateway?.url || 'http://127.0.0.1:18789',
|
||||||
@@ -38,7 +38,8 @@ const CONFIG = {
|
|||||||
bindPassword: conf.auth?.ldap?.bindPassword || '',
|
bindPassword: conf.auth?.ldap?.bindPassword || '',
|
||||||
searchFilter: conf.auth?.ldap?.searchFilter || '(uid={{username}})'
|
searchFilter: conf.auth?.ldap?.searchFilter || '(uid={{username}})'
|
||||||
},
|
},
|
||||||
dataDir: conf.data?.dir || join(__dirname, '../data')
|
dataDir: conf.data?.dir || join(__dirname, '../data'),
|
||||||
|
environment: conf.environment
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure data directory exists
|
// Ensure data directory exists
|
||||||
|
|||||||
Reference in New Issue
Block a user