Files
ontime/apps/server/src/api-data/session/session.service.ts
T
Alex Christoffer Rasmussen c1fcdf7065 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
2026-03-02 06:02:29 -08:00

92 lines
3.2 KiB
TypeScript

import { GetInfo, LinkOptions, OntimeView, SessionStats } from 'ontime-types';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';
import { publicDir } from '../../setup/index.js';
import { socket } from '../../adapters/WebsocketAdapter.js';
import { getLastRequest } from '../../api-integration/integration.controller.js';
import { getCurrentProject } from '../../services/project-service/ProjectService.js';
import { runtimeService } from '../../services/runtime-service/runtime.service.js';
import { getNetworkInterfaces } from '../../utils/network.js';
import { getTimezoneLabel } from '../../utils/time.js';
import { password, routerPrefix } from '../../externals.js';
import { hashPassword } from '../../utils/hash.js';
import { ONTIME_VERSION } from '../../ONTIME_VERSION.js';
import { portManager } from '../../classes/port-manager/PortManager.js';
const startedAt = new Date();
/** Gathers information related to runtime */
export async function getSessionStats(): Promise<SessionStats> {
const { connectedClients, lastConnection } = socket.getStats();
const lastRequest = getLastRequest();
const { filename } = await getCurrentProject();
const { playback } = runtimeService.getRuntimeState();
return {
startedAt: startedAt.toISOString(),
connectedClients,
lastConnection: lastConnection !== null ? lastConnection.toISOString() : null,
lastRequest: lastRequest !== null ? lastRequest.toISOString() : null,
projectName: filename,
playback,
timezone: getTimezoneLabel(startedAt),
version: ONTIME_VERSION,
};
}
/**
* Adds business logic to gathering data for the info endpoint
*/
export async function getInfo(): Promise<GetInfo> {
const { version } = getDataProvider().getSettings();
const { port } = portManager.getPort();
// get nif and inject localhost
const ni = getNetworkInterfaces();
ni.unshift({ name: 'localhost', address: '127.0.0.1' });
return {
networkInterfaces: ni,
version,
serverPort: port,
publicDir: publicDir.root,
};
}
export const hasPassword = Boolean(password);
export const hashedPassword = hasPassword ? hashPassword(password as string) : undefined;
/**
* Generates a pre-authenticated URL by injecting a token in the URL params
*/
export function generateShareUrl(
baseUrl: string,
canonicalPath: string,
{ authenticate, lockConfig, lockNav, preset, prefix = routerPrefix, hash = hashedPassword }: LinkOptions,
): URL {
/**
* URL constructor will throw if given an IP address without protocol
* for the case of IP addresses, we expect that the base URL provides protocol and port
* eg: http://192.168.10.1:4001
*/
const url = new URL(baseUrl);
// companion links point to the root
if (canonicalPath !== '<<companion>>') {
// if the config is locked and we are in a preset, we hide the canonical path
const shouldMaskPath = Boolean(preset) && (canonicalPath === OntimeView.Cuesheet || lockConfig);
const maybePresetPath = shouldMaskPath ? `preset/${preset}` : preset || canonicalPath;
url.pathname = prefix ? `${prefix}/${maybePresetPath}` : maybePresetPath;
if (lockNav) {
url.searchParams.append('n', '1');
}
}
if (authenticate && hash) {
url.searchParams.append('token', hash);
}
return url;
}