diff --git a/apps/client/src/features/sharing/GenerateLinkFormExport.tsx b/apps/client/src/features/sharing/GenerateLinkFormExport.tsx index 569587317..8b4acc102 100644 --- a/apps/client/src/features/sharing/GenerateLinkFormExport.tsx +++ b/apps/client/src/features/sharing/GenerateLinkFormExport.tsx @@ -29,7 +29,7 @@ export default function GenerateLinkFormExport({ lockedPath }: GenerateLinkFormE { value: OntimeView.Timer, label: 'Timer' }, { value: OntimeView.Cuesheet, label: 'Cuesheet' }, { value: OntimeView.Operator, label: 'Operator' }, - { value: '', label: 'Companion' }, + { value: '<>', label: 'Companion' }, ...urlPresetData.map((preset) => ({ value: `preset-${preset.alias}`, label: `URL Preset: ${preset.alias}`, diff --git a/apps/server/src/api-data/session/__tests__/session.service.test.ts b/apps/server/src/api-data/session/__tests__/session.service.test.ts index 4a925df3e..22825e00c 100644 --- a/apps/server/src/api-data/session/__tests__/session.service.test.ts +++ b/apps/server/src/api-data/session/__tests__/session.service.test.ts @@ -27,7 +27,7 @@ describe('generateAuthenticatedUrl()', () => { authenticate: true, hash: '1234', }); - expect(withAuth.toString()).toBe('http://192.168.10.173:4001/timer?token=1234&n=1'); + expect(withAuth.toString()).toBe('http://192.168.10.173:4001/timer?n=1&token=1234'); }); it('generates a link to an unlocked preset', () => { @@ -69,6 +69,17 @@ describe('generateAuthenticatedUrl()', () => { }); expect(withAuth.toString()).toBe('http://192.168.10.173:4001/preset/some-cuesheet-preset'); }); + + it('generates a link for companion', () => { + const withAuth = generateShareUrl('http://192.168.10.173:4001', '<>', { + lockConfig: false, + lockNav: false, + authenticate: true, + preset: undefined, + hash: '1234', + }); + expect(withAuth.toString()).toBe('http://192.168.10.173:4001/?token=1234'); + }); }); describe('for ontime-cloud URLs', () => { @@ -100,7 +111,7 @@ describe('generateAuthenticatedUrl()', () => { prefix: 'prefix', hash: '1234', }); - expect(withAuth.toString()).toBe('https://cloud.getontime.no/prefix/timer?token=1234&n=1'); + expect(withAuth.toString()).toBe('https://cloud.getontime.no/prefix/timer?n=1&token=1234'); }); it('generates a link to an unlocked preset', () => { diff --git a/apps/server/src/api-data/session/session.service.ts b/apps/server/src/api-data/session/session.service.ts index bd867e89d..1d72dad65 100644 --- a/apps/server/src/api-data/session/session.service.ts +++ b/apps/server/src/api-data/session/session.service.ts @@ -64,18 +64,21 @@ export function generateShareUrl( ): URL { const url = new URL(baseUrl); - // 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; + // companion links point to the root + if (canonicalPath !== '<>') { + // 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); } - if (lockNav) { - url.searchParams.append('n', '1'); - } - return url; } diff --git a/apps/server/src/api-data/session/session.validation.ts b/apps/server/src/api-data/session/session.validation.ts index 3903703b4..68509e9b1 100644 --- a/apps/server/src/api-data/session/session.validation.ts +++ b/apps/server/src/api-data/session/session.validation.ts @@ -9,8 +9,6 @@ export const validateGenerateUrl = [ body('lockConfig').isBoolean(), body('lockNav').isBoolean(), body('preset').optional().isString().trim().notEmpty(), - body('prefix').optional().isString().trim().notEmpty(), - body('hash').optional().isString().trim().notEmpty(), requestValidationFunction, ];