Files
BetterDesk/web-nodejs/tests/privilegedPorts.test.js
T
UNITRONIX edfd493be1 fix(console): avoid EACCES crash when binding HTTPS on port 443 (#173)
Security update H-7 runs the console as User=betterdesk, which cannot bind
ports below 1024 without CAP_NET_BIND_SERVICE. Fall back to high ports at
startup, add the capability to systemd when .env uses :443/:80, and handle
EACCES on listen without an unhandled process crash.
2026-06-07 16:29:49 +02:00

76 lines
2.4 KiB
JavaScript

'use strict';
const {
isPrivilegedPort,
resolvePortForCurrentUser,
parseEnvPortSettings,
consoleEnvUsesPrivilegedPorts,
ensureBindCapabilityInServiceUnit,
serviceUnitHasBindCapability,
} = require('../lib/privilegedPorts');
describe('privilegedPorts', () => {
test('isPrivilegedPort detects ports below 1024', () => {
expect(isPrivilegedPort(443)).toBe(true);
expect(isPrivilegedPort(80)).toBe(true);
expect(isPrivilegedPort(1024)).toBe(false);
expect(isPrivilegedPort(5443)).toBe(false);
});
test('parseEnvPortSettings reads HTTPS settings from env content', () => {
const settings = parseEnvPortSettings([
'HTTPS_ENABLED=true',
'HTTPS_PORT=443',
'PORT=80',
'HTTP_REDIRECT_HTTPS=false',
].join('\n'));
expect(settings).toEqual({
port: 80,
httpsPort: 443,
httpsEnabled: true,
httpRedirect: false,
});
});
test('consoleEnvUsesPrivilegedPorts detects HTTPS on 443', () => {
expect(consoleEnvUsesPrivilegedPorts({
httpsEnabled: true,
httpsPort: 443,
port: 5000,
httpRedirect: true,
})).toBe(true);
expect(consoleEnvUsesPrivilegedPorts({
httpsEnabled: true,
httpsPort: 5443,
port: 5000,
httpRedirect: true,
})).toBe(false);
});
test('ensureBindCapabilityInServiceUnit is idempotent', () => {
const base = [
'[Service]',
'User=betterdesk',
'ExecStart=/usr/bin/node server.js',
].join('\n');
const first = ensureBindCapabilityInServiceUnit(base);
expect(first.changed).toBe(true);
expect(serviceUnitHasBindCapability(first.content)).toBe(true);
expect(first.content).toContain('AmbientCapabilities=CAP_NET_BIND_SERVICE');
const second = ensureBindCapabilityInServiceUnit(first.content);
expect(second.changed).toBe(false);
});
test('resolvePortForCurrentUser falls back for privileged ports when not root', () => {
const originalGetuid = process.getuid;
process.getuid = () => 1000;
try {
expect(resolvePortForCurrentUser(443, 5443, 'HTTPS')).toBe(5443);
expect(resolvePortForCurrentUser(5443, 5000, 'HTTPS')).toBe(5443);
} finally {
process.getuid = originalGetuid;
}
});
});