Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Live web UI for `events.log` and `openhab.log` built with Node.js, Express, and
| Variable | Default | Description |
| --- | --- | --- |
| `PORT` | `9001` | HTTP port used by the application |
| `BIND_ADDRESS` | `0.0.0.0` | Network interface address the server listens on. Set to `127.0.0.1` to restrict access to the local host, e.g. when a reverse proxy runs on the same machine. An unbindable address (typo, address not present on this host) makes startup fail loudly instead of binding somewhere unexpected. |
| `OPENHAB_LOG_DIR` | `/var/log/openhab` | Fallback directory for log files |
| `EVENTS_LOG_PATH` | `/var/log/openhab/events.log` | Full path to `events.log` |
| `OPENHAB_LOG_PATH` | `/var/log/openhab/openhab.log` | Full path to `openhab.log` |
Expand Down
2 changes: 2 additions & 0 deletions deploy/systemd/openhab-log-viewer.service
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Environment=CLIENT_MAX_RENDERED_LINES=500
# Uncomment to reject requests whose Host header is not on the allowlist
# (DNS-rebinding mitigation). Comma-separated, no port; use bracketed IPv6:
# Environment=ALLOWED_HOSTS=openhab-pi,192.168.1.10
# Uncomment to restrict the listener, e.g. when a reverse proxy runs on this host:
# Environment=BIND_ADDRESS=127.0.0.1
EnvironmentFile=-/etc/default/openhab-log-viewer
ExecStart=/usr/bin/node dist/server/index.cjs
Restart=always
Expand Down
18 changes: 18 additions & 0 deletions src/server/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { loadConfig } from './config.js';

const CONFIG_ENV_KEYS = [
'PORT',
'BIND_ADDRESS',
'INITIAL_LINES_PER_FILE',
'MAX_BUFFERED_LINES',
'CLIENT_MAX_RENDERED_LINES',
Expand Down Expand Up @@ -45,6 +46,7 @@ describe('loadConfig defaults', () => {
it('uses documented defaults when no env vars are set', () => {
const config = loadConfig();
assert.equal(config.port, 9001);
assert.equal(config.bindAddress, '0.0.0.0');
assert.equal(config.initialLinesPerFile, 500);
assert.equal(config.maxBufferedLines, 2000);
assert.equal(config.clientMaxRenderedLines, 500);
Expand Down Expand Up @@ -143,6 +145,22 @@ describe('loadConfig health details parsing', () => {
});
});

describe('loadConfig bind address parsing', () => {
it('defaults to 0.0.0.0 when unset', () => {
assert.equal(loadConfig().bindAddress, '0.0.0.0');
});

it('uses the configured address', () => {
process.env.BIND_ADDRESS = '127.0.0.1';
assert.equal(loadConfig().bindAddress, '127.0.0.1');
});

it('treats a whitespace-only value as unset', () => {
process.env.BIND_ADDRESS = ' ';
assert.equal(loadConfig().bindAddress, '0.0.0.0');
});
});

describe('loadConfig allowed hosts parsing', () => {
it('defaults to an empty list', () => {
assert.deepEqual(loadConfig().allowedHosts, []);
Expand Down
4 changes: 4 additions & 0 deletions src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ export function loadConfig(): AppConfig {

return {
port: clampInteger('PORT', 9001, 1, 65_535),
// Default '0.0.0.0' preserves current behavior (bind all interfaces). No
// further validation: an unbindable address fails loudly at listen() time
// (see the server's 'error' handler), so any string is passed through.
bindAddress: process.env.BIND_ADDRESS?.trim() || '0.0.0.0',
initialLinesPerFile: clampInteger('INITIAL_LINES_PER_FILE', 500, 1, 100_000),
maxBufferedLines: clampInteger('MAX_BUFFERED_LINES', 2_000, 100, 1_000_000),
// The browser hard-caps rendering at CLIENT_MAX_RENDERED_LINES_CAP (500) for
Expand Down
9 changes: 7 additions & 2 deletions src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,13 @@ async function main(): Promise<void> {
app.use(htmlLimiter);
app.use(createSpaFallback(clientDistDir));

const server = app.listen(config.port, () => {
console.log(`OpenHab Log Viewer listening on port ${config.port}`);
const server = app.listen(config.port, config.bindAddress, () => {
console.log(`OpenHab Log Viewer listening on ${config.bindAddress}:${config.port}`);
});

server.on('error', (error) => {
console.error('[startup] Failed to bind server:', error);
process.exit(1);
});

const shutdown = createShutdown({ tailers, sseHub, server });
Expand Down
1 change: 1 addition & 0 deletions src/server/routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const NO_HEARTBEAT = 1_000_000_000;
function baseConfig(overrides: Partial<AppConfig> = {}): AppConfig {
return {
port: 9001,
bindAddress: '0.0.0.0',
initialLinesPerFile: 500,
maxBufferedLines: 2000,
clientMaxRenderedLines: 500,
Expand Down
1 change: 1 addition & 0 deletions src/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface SourceConfig {

export interface AppConfig {
port: number;
bindAddress: string;
initialLinesPerFile: number;
maxBufferedLines: number;
clientMaxRenderedLines: number;
Expand Down