Skip to content
Open
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
17 changes: 0 additions & 17 deletions meteor/server/Settings.ts

This file was deleted.

6 changes: 3 additions & 3 deletions meteor/server/__tests__/cronjobs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import {
setupDefaultStudioEnvironment,
} from '../../__mocks__/helpers/database'
import { DBSegment } from '@sofie-automation/corelib/dist/dataModel/Segment'
import { Settings } from '../Settings'
import { DEFAULT_MAXIMUM_DATA_AGE } from '@sofie-automation/shared-lib/dist/core/constants'
import { SofieIngestCacheType } from '@sofie-automation/corelib/dist/dataModel/SofieIngestDataCache'
import { ObjectOverrideSetOp, ObjectWithOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
import { PartInstance } from '@sofie-automation/corelib/dist/dataModel/PartInstance'
Expand Down Expand Up @@ -442,7 +442,7 @@ describe('cronjobs', () => {
clientAddress: '',
context: '',
method: '',
timestamp: lib.getCurrentTime() - Settings.maximumDataAge - 1000,
timestamp: lib.getCurrentTime() - DEFAULT_MAXIMUM_DATA_AGE - 1000,
})

await runCronjobs()
Expand Down Expand Up @@ -477,7 +477,7 @@ describe('cronjobs', () => {
type: SnapshotType.DEBUG,
version: '',
// Very old:
created: lib.getCurrentTime() - Settings.maximumDataAge - 1000,
created: lib.getCurrentTime() - DEFAULT_MAXIMUM_DATA_AGE - 1000,
})

await runCronjobs()
Expand Down
29 changes: 20 additions & 9 deletions meteor/server/api/cleanup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import {
getOrphanedPackageInfos,
removePackageInfos,
} from './studio/lib'
import { Settings } from '../Settings'
import { getCoreSystemAsync } from '../coreSystem/collection'
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
import { DEFAULT_MAXIMUM_DATA_AGE } from '@sofie-automation/shared-lib/dist/core/constants'
import { CollectionName } from '@sofie-automation/corelib/dist/dataModel/Collections'
import {
BlueprintId,
Expand Down Expand Up @@ -81,6 +83,18 @@ export async function cleanupOldDataInner(actuallyCleanup = false): Promise<Coll
if (notAllowedReason) return `Could not run the cleanup function due to: ${notAllowedReason}`
}

const coreSystem = await getCoreSystemAsync()
const systemSettings = coreSystem && applyAndValidateOverrides(coreSystem.settingsWithOverrides).obj
// Guard against a misconfigured value (<= 0, NaN, Infinity) which would otherwise cause overly-aggressive
// purging of recent data. Fall back to the default in that case.
const configuredMaximumDataAge = systemSettings?.maximumDataAge
const maximumDataAge =
typeof configuredMaximumDataAge === 'number' &&
Number.isFinite(configuredMaximumDataAge) &&
configuredMaximumDataAge > 0
? configuredMaximumDataAge
: DEFAULT_MAXIMUM_DATA_AGE

Comment thread
coderabbitai[bot] marked this conversation as resolved.
const result: CollectionCleanupResult = {}
const addToResult = (collectionName: CollectionName, docsToRemove: number) => {
if (!result[collectionName]) {
Expand Down Expand Up @@ -275,7 +289,7 @@ export async function cleanupOldDataInner(actuallyCleanup = false): Promise<Coll
{
// Remove any from long running rundowns where they have long since expired:
reset: true,
'timings.plannedStoppedPlayback': { $lt: getCurrentTime() - Settings.maximumDataAge },
'timings.plannedStoppedPlayback': { $lt: getCurrentTime() - maximumDataAge },
'part._id': { $nin: partIds },
},
],
Expand All @@ -295,16 +309,13 @@ export async function cleanupOldDataInner(actuallyCleanup = false): Promise<Coll
// Evaluations
{
await removeByQuery(Evaluations, {
timestamp: { $lt: getCurrentTime() - Settings.maximumDataAge },
timestamp: { $lt: getCurrentTime() - maximumDataAge },
})
}
// ExternalMessageQueue
{
await removeByQuery(ExternalMessageQueue, {
$or: [
{ created: { $lt: getCurrentTime() - Settings.maximumDataAge } },
{ expires: { $lt: getCurrentTime() } },
],
$or: [{ created: { $lt: getCurrentTime() - maximumDataAge } }, { expires: { $lt: getCurrentTime() } }],
})
}
// PackageInfos
Expand All @@ -328,14 +339,14 @@ export async function cleanupOldDataInner(actuallyCleanup = false): Promise<Coll
// Snapshots
{
await removeByQuery(Snapshots, {
created: { $lt: getCurrentTime() - Settings.maximumDataAge },
created: { $lt: getCurrentTime() - maximumDataAge },
})
}

// UserActionsLog
{
await removeByQuery(UserActionsLog, {
timestamp: { $lt: getCurrentTime() - Settings.maximumDataAge },
timestamp: { $lt: getCurrentTime() - maximumDataAge },
})
}
// Workers
Expand Down
7 changes: 6 additions & 1 deletion meteor/server/api/rest/koa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { logger } from '../../logging'
import { PackageInfo } from '../../coreSystem'
import { profiler } from '../profiler'
import fs from 'fs/promises'
import type { IExtendedSettings } from '@sofie-automation/meteor-lib/dist/Settings'
import { ENABLE_HEADER_AUTH } from '../../security/auth'

declare module 'http' {
interface IncomingMessage {
Expand Down Expand Up @@ -123,7 +125,10 @@ function getExtendedMeteorRuntimeConfig() {
return `window.__meteor_runtime_config__ = (${JSON.stringify({
// @ts-expect-error missing types for internal meteor detail
...__meteor_runtime_config__,
sofieVersionExtended: versionExtended,
...({
sofieVersionExtended: versionExtended,
enableHeaderAuth: ENABLE_HEADER_AUTH,
} satisfies IExtendedSettings),
})})`
}

Expand Down
16 changes: 16 additions & 0 deletions meteor/server/api/rest/v1/typeConversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,15 @@ export function studioSettingsFrom(apiStudioSettings: APIStudioSettings): Comple
shelfAdlibButtonSize: apiStudioSettings.shelfAdlibButtonSize ?? ShelfButtonSize.LARGE,
mockPieceContentStatus: apiStudioSettings.mockPieceContentStatus,
rundownGlobalPiecesPrepareTime: apiStudioSettings.rundownGlobalPiecesPrepareTime,
autoRewindLeavingSegment: apiStudioSettings.autoRewindLeavingSegment,
disableBlurBorder: apiStudioSettings.disableBlurBorder,
allowGrabbingTimeline: apiStudioSettings.allowGrabbingTimeline,
useCountdownToFreezeFrame: apiStudioSettings.useCountdownToFreezeFrame,
// defaultShelfDisplayOptions is intentionally not exposed through the REST API
defaultShelfDisplayOptions: undefined,
defaultDisplayDuration: apiStudioSettings.defaultDisplayDuration,
defaultTimeScale: apiStudioSettings.defaultTimeScale,
followOnAirSegmentsHistory: apiStudioSettings.followOnAirSegmentsHistory,
}
}

Expand Down Expand Up @@ -456,6 +465,13 @@ export function APIStudioSettingsFrom(settings: IStudioSettings): Complete<APISt
shelfAdlibButtonSize: settings.shelfAdlibButtonSize,
mockPieceContentStatus: settings.mockPieceContentStatus,
rundownGlobalPiecesPrepareTime: settings.rundownGlobalPiecesPrepareTime,
autoRewindLeavingSegment: settings.autoRewindLeavingSegment,
disableBlurBorder: settings.disableBlurBorder,
allowGrabbingTimeline: settings.allowGrabbingTimeline,
useCountdownToFreezeFrame: settings.useCountdownToFreezeFrame,
defaultDisplayDuration: settings.defaultDisplayDuration,
defaultTimeScale: settings.defaultTimeScale,
followOnAirSegmentsHistory: settings.followOnAirSegmentsHistory,
}
}

Expand Down
15 changes: 14 additions & 1 deletion meteor/server/api/studio/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ import { MethodContextAPI, MethodContext } from '../methodContext'
import { wrapDefaultObject } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
import { PeripheralDeviceId, StudioId } from '@sofie-automation/corelib/dist/dataModel/Ids'
import { logger } from '../../logging'
import { DEFAULT_MINIMUM_TAKE_SPAN } from '@sofie-automation/shared-lib/dist/core/constants'
import {
DEFAULT_MINIMUM_TAKE_SPAN,
DEFAULT_DISPLAY_DURATION,
DEFAULT_SHELF_DISPLAY_OPTIONS,
DEFAULT_TIME_SCALE,
} from '@sofie-automation/shared-lib/dist/core/constants'
import { UserPermissions } from '@sofie-automation/meteor-lib/dist/userPermissions'
import { assertConnectionHasOneOfPermissions } from '../../security/auth'
import { ShelfButtonSize } from '@sofie-automation/shared-lib/dist/core/model/StudioSettings'
Expand Down Expand Up @@ -66,6 +71,14 @@ export async function insertStudioInner(newId?: StudioId): Promise<StudioId> {
enableBuckets: true,
enableEvaluationForm: true,
shelfAdlibButtonSize: ShelfButtonSize.LARGE,
autoRewindLeavingSegment: true,
disableBlurBorder: false,
allowGrabbingTimeline: true,
useCountdownToFreezeFrame: true,
defaultShelfDisplayOptions: DEFAULT_SHELF_DISPLAY_OPTIONS,
defaultDisplayDuration: DEFAULT_DISPLAY_DURATION,
defaultTimeScale: DEFAULT_TIME_SCALE,
followOnAirSegmentsHistory: 0,
}),
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
Expand Down
54 changes: 0 additions & 54 deletions meteor/server/api/systemTime/ntpTimeChecker.ts

This file was deleted.

8 changes: 8 additions & 0 deletions meteor/server/coreSystem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { SYSTEM_ID, GENESIS_SYSTEM_VERSION } from '@sofie-automation/meteor-lib/
import { parseVersion } from '../systemStatus/semverUtils'
import { getCurrentTime } from '../lib/lib'
import { stringifyError } from '@sofie-automation/shared-lib/dist/lib/stringifyError'
import {
DEFAULT_MAXIMUM_DATA_AGE,
DEFAULT_CONFIRM_KEY_CODE,
DEFAULT_POISON_KEY,
} from '@sofie-automation/shared-lib/dist/core/constants'
import { Meteor } from 'meteor/meteor'
import { prepareMigration, runMigration } from '../migration/databaseMigration'
import { CURRENT_SYSTEM_VERSION } from '../migration/currentSystemVersion'
Expand Down Expand Up @@ -79,6 +84,9 @@ async function initializeCoreSystem() {
heading: '',
message: '',
},
maximumDataAge: DEFAULT_MAXIMUM_DATA_AGE,
confirmKeyCode: DEFAULT_CONFIRM_KEY_CODE,
poisonKey: DEFAULT_POISON_KEY,
}),
lastBlueprintConfig: undefined,
})
Expand Down
7 changes: 7 additions & 0 deletions meteor/server/lib/rest/v1/studios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,11 @@ export interface APIStudioSettings {
shelfAdlibButtonSize?: Exclude<ShelfButtonSize, ShelfButtonSize.INHERIT>
mockPieceContentStatus?: boolean
rundownGlobalPiecesPrepareTime?: number
autoRewindLeavingSegment?: boolean
disableBlurBorder?: boolean
allowGrabbingTimeline?: boolean
useCountdownToFreezeFrame?: boolean
defaultDisplayDuration?: number
defaultTimeScale?: number
followOnAirSegmentsHistory?: number
}
4 changes: 2 additions & 2 deletions meteor/server/migration/1_40_0.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Meteor } from 'meteor/meteor'
import { addMigrationSteps } from './databaseMigration'
import { Settings } from '../Settings'
import { Studios } from '../collections'

// Release 40 (Skipped)
Expand Down Expand Up @@ -36,7 +36,7 @@ interface ISettingsOld {
maxAllowedDiff: number
}
}
const OldSettings = Settings as Partial<ISettingsOld>
const OldSettings = (Meteor.settings.public ?? {}) as Partial<ISettingsOld>
const oldFrameRate = OldSettings.frameRate ?? 25

export const addSteps = addMigrationSteps('1.40.0', [
Expand Down
8 changes: 8 additions & 0 deletions meteor/server/migration/upgrades/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import { CoreSystemId } from '@sofie-automation/corelib/dist/dataModel/Ids'
import { DEFAULT_CORE_TRIGGERS } from './defaultSystemActionTriggers'
import { protectString } from '@sofie-automation/corelib/dist/protectedString'
import { ICoreSystemSettings } from '@sofie-automation/shared-lib/dist/core/model/CoreSystemSettings'
import {
DEFAULT_MAXIMUM_DATA_AGE,
DEFAULT_CONFIRM_KEY_CODE,
DEFAULT_POISON_KEY,
} from '@sofie-automation/shared-lib/dist/core/constants'

export async function runUpgradeForCoreSystem(coreSystemId: CoreSystemId): Promise<void> {
logger.info(`Running upgrade for CoreSystem`)
Expand Down Expand Up @@ -102,6 +107,9 @@ function generateDefaultSystemConfig(): BlueprintResultApplySystemConfig {
heading: '',
message: '',
},
maximumDataAge: DEFAULT_MAXIMUM_DATA_AGE,
confirmKeyCode: DEFAULT_CONFIRM_KEY_CODE,
poisonKey: DEFAULT_POISON_KEY,
},
triggeredActions: Object.values<IBlueprintTriggeredActions>(DEFAULT_CORE_TRIGGERS),
}
Expand Down
14 changes: 10 additions & 4 deletions meteor/server/security/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
USER_PERMISSIONS_HEADER,
UserPermissions,
} from '@sofie-automation/meteor-lib/dist/userPermissions'
import { Settings } from '../Settings'
import { Meteor } from 'meteor/meteor'
import Koa from 'koa'
import { triggerWriteAccess } from './securityVerify'
Expand All @@ -12,8 +11,15 @@ import { CollectionName } from '@sofie-automation/corelib/dist/dataModel/Collect

export type RequestCredentials = Meteor.Connection | Koa.ParameterizedContext

/**
* Whether http-header based security measures are enabled.
* Configured via the `SOFIE_ENABLE_HEADER_AUTH` environment variable (`1` or `true` to enable).
*/
export const ENABLE_HEADER_AUTH =
process.env.SOFIE_ENABLE_HEADER_AUTH === '1' || process.env.SOFIE_ENABLE_HEADER_AUTH?.toLowerCase() === 'true'

export function parseConnectionPermissions(conn: RequestCredentials): UserPermissions {
if (!Settings.enableHeaderAuth) {
if (!ENABLE_HEADER_AUTH) {
// If auth is disabled, return all permissions
return {
studio: true,
Expand Down Expand Up @@ -49,7 +55,7 @@ export function assertConnectionHasOneOfPermissions(
if (!conn) throw new Meteor.Error(403, 'Can only be invoked by clients')

// Skip if auth is disabled
if (!Settings.enableHeaderAuth) return
if (!ENABLE_HEADER_AUTH) return

const permissions = parseConnectionPermissions(conn)
for (const permission of allowedPermissions) {
Expand All @@ -70,7 +76,7 @@ export function checkHasOneOfPermissions(
triggerWriteAccess()

// Skip if auth is disabled
if (!Settings.enableHeaderAuth) return true
if (!ENABLE_HEADER_AUTH) return true

if (!permissions) throw new Meteor.Error(403, 'Permissions is null')

Expand Down
Loading
Loading