Remove serverport from project file (#1957)

* feat: get server port from app satate or env

optional startup port from env will always override

function for parsing port from env

populate default port in app state

add test for migration

* bump version
This commit is contained in:
Alex Christoffer Rasmussen
2026-03-02 06:02:29 -08:00
committed by GitHub
parent 1fe58e21be
commit c1fcdf7065
38 changed files with 593 additions and 193 deletions
@@ -12,7 +12,6 @@ describe('parseSettings()', () => {
expect(result).toBeTypeOf('object');
expect(result).toMatchObject({
version: expect.any(String),
serverPort: 4001,
editorKey: null,
operatorKey: null,
timeFormat: '24',
@@ -18,7 +18,6 @@ export function parseSettings(data: Partial<DatabaseModel>): Settings {
return {
version: defaultSettings.version,
serverPort: data.settings.serverPort ?? defaultSettings.serverPort,
editorKey: data.settings.editorKey ?? defaultSettings.editorKey,
operatorKey: data.settings.operatorKey ?? defaultSettings.operatorKey,
timeFormat: data.settings.timeFormat ?? defaultSettings.timeFormat,
@@ -1,25 +1,29 @@
import express from 'express';
import { matchedData } from 'express-validator';
import type { Request, Response } from 'express';
import { deepEqual } from 'fast-equals';
import express from "express";
import { matchedData } from "express-validator";
import type { Request, Response } from "express";
import { deepEqual } from "fast-equals";
import { ErrorResponse, RefetchKey, Settings } from 'ontime-types';
import { getErrorMessage, obfuscate } from 'ontime-utils';
import { ErrorResponse, PortInfo, RefetchKey, Settings } from "ontime-types";
import { getErrorMessage, obfuscate } from "ontime-utils";
import { validateSettings, validateWelcomeDialog } from './settings.validation.js';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';
import * as appState from '../../services/app-state-service/AppStateService.js';
import { isDocker } from '../../setup/environment.js';
import { sendRefetch } from '../../adapters/WebsocketAdapter.js';
import {
validateSettings,
validateWelcomeDialog,
validateServerPort,
} from "./settings.validation.js";
import { getDataProvider } from "../../classes/data-provider/DataProvider.js";
import * as appState from "../../services/app-state-service/AppStateService.js";
import { sendRefetch } from "../../adapters/WebsocketAdapter.js";
import { portManager } from "../../classes/port-manager/PortManager.js";
export const router = express.Router();
router.post('/welcomedialog', validateWelcomeDialog, async (req: Request, res: Response) => {
router.post("/welcomedialog", validateWelcomeDialog, async (req: Request, res: Response) => {
const show = await appState.setShowWelcomeDialog(req.body.show);
res.status(200).json({ show });
});
router.get('/', (_req: Request, res: Response<Settings>) => {
router.get("/", (_req: Request, res: Response<Settings>) => {
const settings = getDataProvider().getSettings();
const obfuscatedSettings = { ...settings };
if (settings.editorKey) {
@@ -33,26 +37,52 @@ router.get('/', (_req: Request, res: Response<Settings>) => {
res.status(200).json(obfuscatedSettings);
});
router.post('/', validateSettings, async (req: Request, res: Response<Settings | ErrorResponse>) => {
router.post(
"/",
validateSettings,
async (req: Request, res: Response<Settings | ErrorResponse>) => {
try {
const data = matchedData<Settings>(req);
const settings = getDataProvider().getSettings();
data.version = settings.version;
if (!deepEqual(data, settings)) {
await getDataProvider().setSettings(data);
sendRefetch(RefetchKey.Settings);
}
res.status(200).json(data);
} catch (error) {
const message = getErrorMessage(error);
res.status(400).json({ message });
}
},
);
router.get("/serverport", (_req: Request, res: Response<PortInfo | ErrorResponse>) => {
try {
const data = matchedData<Settings>(req);
const settings = getDataProvider().getSettings();
if (isDocker && settings.serverPort !== data.serverPort) {
res.status(403).json({ message: 'Can`t change port when running inside docker' });
return;
}
data.version = settings.version;
if (!deepEqual(data, settings)) {
await getDataProvider().setSettings(data);
sendRefetch(RefetchKey.Settings);
}
res.status(200).json(data);
const { port, pendingRestart } = portManager.getPort();
res.status(200).json({ port, pendingRestart });
} catch (error) {
const message = getErrorMessage(error);
res.status(400).json({ message });
res.status(500).json({ message });
}
});
router.post(
"/serverport",
validateServerPort,
async (req: Request, res: Response<PortInfo | ErrorResponse>) => {
try {
const { serverPort } = matchedData<{ serverPort: number }>(req);
portManager.changePort(serverPort);
const { port, pendingRestart } = portManager.getPort();
res.status(200).json({ port, pendingRestart });
} catch (error) {
const message = getErrorMessage(error);
res.status(400).json({ message });
}
},
);
@@ -26,7 +26,11 @@ export const validateSettings = [
pinValidator('operatorKey'),
body('timeFormat').isString().isIn(['12', '24']).withMessage('Time format can only be "12" or "24"'),
body('language').isString().trim().notEmpty(),
body('serverPort').isPort().withMessage('Invalid value found for server port').toInt(),
requestValidationFunction,
];
export const validateServerPort = [
body('serverPort').isPort().withMessage('Invalid value found for server port').toInt(),
requestValidationFunction,
];