Files
ontime/apps/server/src/api-data/session/session.service.ts
T
Alex Christoffer Rasmussen 7c1d2f4554 refactor: small cleanups (#2059)
* refactor: remove unneeded async

* chore: add express Router type to all routes

* refactor: don't use index in react key

* refactor: correctly get error message in excel route

* refactor: avoid exporting muteable values
2026-04-26 17:32:50 +02:00

92 lines
3.2 KiB
TypeScript

import { GetInfo, LinkOptions, OntimeView, SessionStats } from 'ontime-types';
import { socket } from '../../adapters/WebsocketAdapter.js';
import { getLastRequest } from '../../api-integration/integration.controller.js';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';
import { portManager } from '../../classes/port-manager/PortManager.js';
import { password, routerPrefix } from '../../externals.js';
import { ONTIME_VERSION } from '../../ONTIME_VERSION.js';
import { getCurrentProject } from '../../services/project-service/ProjectService.js';
import { runtimeService } from '../../services/runtime-service/runtime.service.js';
import { publicDir } from '../../setup/index.js';
import { hashPassword } from '../../utils/hash.js';
import { getNetworkInterfaces } from '../../utils/network.js';
import { getTimezoneLabel } from '../../utils/time.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 function getInfo(): 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;
}