diff --git a/server/controllers/client.ts b/server/controllers/client.ts index 022a17ff4..35e5af9d1 100644 --- a/server/controllers/client.ts +++ b/server/controllers/client.ts @@ -21,8 +21,9 @@ const testEmbedPath = join(distPath, 'standalone', 'videos', 'test-embed.html') // Do not use a template engine for a so little thing clientsRouter.use('/videos/watch/playlist/:id', asyncMiddleware(generateWatchPlaylistHtmlPage)) clientsRouter.use('/videos/watch/:id', asyncMiddleware(generateWatchHtmlPage)) -clientsRouter.use('/accounts/:nameWithHost', asyncMiddleware(generateAccountHtmlPage)) -clientsRouter.use('/video-channels/:nameWithHost', asyncMiddleware(generateVideoChannelHtmlPage)) +clientsRouter.use([ '/accounts/:nameWithHost', '/a/:nameWithHost' ], asyncMiddleware(generateAccountHtmlPage)) +clientsRouter.use([ '/video-channels/:nameWithHost', '/c/:nameWithHost' ], asyncMiddleware(generateVideoChannelHtmlPage)) +clientsRouter.use('/@:nameWithHost', asyncMiddleware(generateActorHtmlPage)) const embedMiddlewares = [ CONFIG.CSP.ENABLED @@ -155,6 +156,12 @@ async function generateVideoChannelHtmlPage (req: express.Request, res: express. return sendHTML(html, res) } +async function generateActorHtmlPage (req: express.Request, res: express.Response) { + const html = await ClientHtml.getActorHTMLPage(req.params.nameWithHost, req, res) + + return sendHTML(html, res) +} + async function generateManifest (req: express.Request, res: express.Response) { const manifestPhysicalPath = join(root(), 'client', 'dist', 'manifest.webmanifest') const manifestJson = await readFile(manifestPhysicalPath, 'utf8') diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts index 203bd3893..cac9edb30 100644 --- a/server/lib/client-html.ts +++ b/server/lib/client-html.ts @@ -196,11 +196,24 @@ class ClientHtml { } static async getAccountHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { - return this.getAccountOrChannelHTMLPage(() => AccountModel.loadByNameWithHost(nameWithHost), req, res) + const accountModelPromise = AccountModel.loadByNameWithHost(nameWithHost) + return this.getAccountOrChannelHTMLPage(() => accountModelPromise, req, res) } static async getVideoChannelHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { - return this.getAccountOrChannelHTMLPage(() => VideoChannelModel.loadByNameWithHostAndPopulateAccount(nameWithHost), req, res) + const videoChannelModelPromise = VideoChannelModel.loadByNameWithHostAndPopulateAccount(nameWithHost) + return this.getAccountOrChannelHTMLPage(() => videoChannelModelPromise, req, res) + } + + static async getActorHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { + const accountModel = await AccountModel.loadByNameWithHost(nameWithHost) + + if (accountModel) { + return this.getAccountOrChannelHTMLPage(() => new Promise(resolve => resolve(accountModel)), req, res) + } else { + const videoChannelModelPromise = VideoChannelModel.loadByNameWithHostAndPopulateAccount(nameWithHost) + return this.getAccountOrChannelHTMLPage(() => videoChannelModelPromise, req, res) + } } static async getEmbedHTML () { diff --git a/server/tests/client.ts b/server/tests/client.ts index 3c99bcd1f..e76220631 100644 --- a/server/tests/client.ts +++ b/server/tests/client.ts @@ -140,27 +140,51 @@ describe('Test a client controllers', function () { describe('Open Graph', function () { it('Should have valid Open Graph tags on the account page', async function () { - const res = await request(servers[0].url) + const accountPageTests = (res) => { + expect(res.text).to.contain(``) + expect(res.text).to.contain(``) + expect(res.text).to.contain('') + expect(res.text).to.contain(``) + } + + accountPageTests(await request(servers[0].url) .get('/accounts/' + servers[0].user.username) .set('Accept', 'text/html') - .expect(HttpStatusCode.OK_200) + .expect(HttpStatusCode.OK_200)) - expect(res.text).to.contain(``) - expect(res.text).to.contain(``) - expect(res.text).to.contain('') - expect(res.text).to.contain(``) + accountPageTests(await request(servers[0].url) + .get('/a/' + servers[0].user.username) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) + + accountPageTests(await request(servers[0].url) + .get('/@' + servers[0].user.username) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) }) it('Should have valid Open Graph tags on the channel page', async function () { - const res = await request(servers[0].url) + const channelPageOGtests = (res) => { + expect(res.text).to.contain(``) + expect(res.text).to.contain(``) + expect(res.text).to.contain('') + expect(res.text).to.contain(``) + } + + channelPageOGtests(await request(servers[0].url) .get('/video-channels/' + servers[0].videoChannel.name) .set('Accept', 'text/html') - .expect(HttpStatusCode.OK_200) + .expect(HttpStatusCode.OK_200)) - expect(res.text).to.contain(``) - expect(res.text).to.contain(``) - expect(res.text).to.contain('') - expect(res.text).to.contain(``) + channelPageOGtests(await request(servers[0].url) + .get('/c/' + servers[0].videoChannel.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) + + channelPageOGtests(await request(servers[0].url) + .get('/@' + servers[0].videoChannel.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) }) it('Should have valid Open Graph tags on the watch page with video id', async function () { @@ -227,27 +251,51 @@ describe('Test a client controllers', function () { }) it('Should have valid twitter card on the account page', async function () { - const res = await request(servers[0].url) + const accountPageTests = (res) => { + expect(res.text).to.contain('') + expect(res.text).to.contain('') + expect(res.text).to.contain(``) + expect(res.text).to.contain(``) + } + + accountPageTests(await request(servers[0].url) .get('/accounts/' + account.name) .set('Accept', 'text/html') - .expect(HttpStatusCode.OK_200) + .expect(HttpStatusCode.OK_200)) - expect(res.text).to.contain('') - expect(res.text).to.contain('') - expect(res.text).to.contain(``) - expect(res.text).to.contain(``) + accountPageTests(await request(servers[0].url) + .get('/a/' + account.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) + + accountPageTests(await request(servers[0].url) + .get('/@' + account.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) }) it('Should have valid twitter card on the channel page', async function () { - const res = await request(servers[0].url) + const channelPageTests = (res) => { + expect(res.text).to.contain('') + expect(res.text).to.contain('') + expect(res.text).to.contain(``) + expect(res.text).to.contain(``) + } + + channelPageTests(await request(servers[0].url) .get('/video-channels/' + servers[0].videoChannel.name) .set('Accept', 'text/html') - .expect(HttpStatusCode.OK_200) + .expect(HttpStatusCode.OK_200)) - expect(res.text).to.contain('') - expect(res.text).to.contain('') - expect(res.text).to.contain(``) - expect(res.text).to.contain(``) + channelPageTests(await request(servers[0].url) + .get('/c/' + servers[0].videoChannel.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) + + channelPageTests(await request(servers[0].url) + .get('/@' + servers[0].videoChannel.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) }) it('Should have valid twitter card if Twitter is whitelisted', async function () { @@ -275,21 +323,45 @@ describe('Test a client controllers', function () { expect(resVideoPlaylistRequest.text).to.contain('') expect(resVideoPlaylistRequest.text).to.contain('') - const resAccountRequest = await request(servers[0].url) + const accountTests = (res) => { + expect(res.text).to.contain('') + expect(res.text).to.contain('') + } + + accountTests(await request(servers[0].url) .get('/accounts/' + account.name) .set('Accept', 'text/html') - .expect(HttpStatusCode.OK_200) + .expect(HttpStatusCode.OK_200)) - expect(resAccountRequest.text).to.contain('') - expect(resAccountRequest.text).to.contain('') + accountTests(await request(servers[0].url) + .get('/a/' + account.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) - const resChannelRequest = await request(servers[0].url) + accountTests(await request(servers[0].url) + .get('/@' + account.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) + + const channelTests = (res) => { + expect(res.text).to.contain('') + expect(res.text).to.contain('') + } + + channelTests(await request(servers[0].url) .get('/video-channels/' + servers[0].videoChannel.name) .set('Accept', 'text/html') - .expect(HttpStatusCode.OK_200) + .expect(HttpStatusCode.OK_200)) - expect(resChannelRequest.text).to.contain('') - expect(resChannelRequest.text).to.contain('') + channelTests(await request(servers[0].url) + .get('/c/' + servers[0].videoChannel.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) + + channelTests(await request(servers[0].url) + .get('/@' + servers[0].videoChannel.name) + .set('Accept', 'text/html') + .expect(HttpStatusCode.OK_200)) }) }) @@ -335,13 +407,23 @@ describe('Test a client controllers', function () { }) it('Should use the original account URL for the canonical tag', async function () { - const res = await makeHTMLRequest(servers[1].url, '/accounts/root@' + servers[0].host) - expect(res.text).to.contain(``) + const accountURLtest = (res) => { + expect(res.text).to.contain(``) + } + + accountURLtest(await makeHTMLRequest(servers[1].url, '/accounts/root@' + servers[0].host)) + accountURLtest(await makeHTMLRequest(servers[1].url, '/a/root@' + servers[0].host)) + accountURLtest(await makeHTMLRequest(servers[1].url, '/@root@' + servers[0].host)) }) it('Should use the original channel URL for the canonical tag', async function () { - const res = await makeHTMLRequest(servers[1].url, '/video-channels/root_channel@' + servers[0].host) - expect(res.text).to.contain(``) + const channelURLtests = (res) => { + expect(res.text).to.contain(``) + } + + channelURLtests(await makeHTMLRequest(servers[1].url, '/video-channels/root_channel@' + servers[0].host)) + channelURLtests(await makeHTMLRequest(servers[1].url, '/c/root_channel@' + servers[0].host)) + channelURLtests(await makeHTMLRequest(servers[1].url, '/@root_channel@' + servers[0].host)) }) it('Should use the original playlist URL for the canonical tag', async function () {