diff --git a/services/web/app/src/Features/PublishedPresentation/PublishedPresentationController.mjs b/services/web/app/src/Features/PublishedPresentation/PublishedPresentationController.mjs index 8df698cd8d..3ae499bdac 100644 --- a/services/web/app/src/Features/PublishedPresentation/PublishedPresentationController.mjs +++ b/services/web/app/src/Features/PublishedPresentation/PublishedPresentationController.mjs @@ -6,7 +6,9 @@ import SessionManager from '../Authentication/SessionManager.mjs' import PublishedPresentationManager from './PublishedPresentationManager.mjs' function _publicUrl(token) { - return `${Settings.siteUrl}/p/${token}` + // Trailing slash so the deck's relative asset paths (e.g. main_files/...) + // resolve under /p/:token/ rather than /p/. + return `${Settings.siteUrl}/p/${token}/` } function _serialize(record) { @@ -63,6 +65,12 @@ async function serve(req, res) { const record = await PublishedPresentationManager.promises.getByToken(token) if (!record) return res.status(404).send('Presentation not found') + // Normalise the bare token URL to a trailing slash so the deck's relative + // asset references resolve under /p/:token/ instead of /p/. + if (!req.params.file && !req.path.endsWith('/')) { + return res.redirect(301, `/p/${encodeURIComponent(token)}/`) + } + if ( record.visibility === 'private' && !SessionManager.getLoggedInUserId(req.session)