Add filter:html.client.json-ld.result hook

This commit is contained in:
Chocobozzz 2023-03-24 18:37:55 +01:00
parent 80d7d180a3
commit d91ce83d39
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
4 changed files with 55 additions and 11 deletions

View File

@ -27,9 +27,10 @@ import { AccountModel } from '../models/account/account'
import { VideoModel } from '../models/video/video' import { VideoModel } from '../models/video/video'
import { VideoChannelModel } from '../models/video/video-channel' import { VideoChannelModel } from '../models/video/video-channel'
import { VideoPlaylistModel } from '../models/video/video-playlist' import { VideoPlaylistModel } from '../models/video/video-playlist'
import { MAccountActor, MChannelActor } from '../types/models' import { MAccountActor, MChannelActor, MVideo, MVideoPlaylist } from '../types/models'
import { getActivityStreamDuration } from './activitypub/activity' import { getActivityStreamDuration } from './activitypub/activity'
import { getBiggestActorImage } from './actor-image' import { getBiggestActorImage } from './actor-image'
import { Hooks } from './plugins/hooks'
import { ServerConfigManager } from './server-config-manager' import { ServerConfigManager } from './server-config-manager'
type Tags = { type Tags = {
@ -64,6 +65,11 @@ type Tags = {
} }
} }
type HookContext = {
video?: MVideo
playlist?: MVideoPlaylist
}
class ClientHtml { class ClientHtml {
private static htmlCache: { [path: string]: string } = {} private static htmlCache: { [path: string]: string } = {}
@ -129,7 +135,7 @@ class ClientHtml {
const twitterCard = CONFIG.SERVICES.TWITTER.WHITELISTED ? 'player' : 'summary_large_image' const twitterCard = CONFIG.SERVICES.TWITTER.WHITELISTED ? 'player' : 'summary_large_image'
const schemaType = 'VideoObject' const schemaType = 'VideoObject'
customHtml = ClientHtml.addTags(customHtml, { customHtml = await ClientHtml.addTags(customHtml, {
url, url,
originUrl, originUrl,
escapedSiteName: escapeHTML(siteName), escapedSiteName: escapeHTML(siteName),
@ -141,7 +147,7 @@ class ClientHtml {
ogType, ogType,
twitterCard, twitterCard,
schemaType schemaType
}) }, { video })
return customHtml return customHtml
} }
@ -193,7 +199,7 @@ class ClientHtml {
const twitterCard = CONFIG.SERVICES.TWITTER.WHITELISTED ? 'player' : 'summary' const twitterCard = CONFIG.SERVICES.TWITTER.WHITELISTED ? 'player' : 'summary'
const schemaType = 'ItemList' const schemaType = 'ItemList'
customHtml = ClientHtml.addTags(customHtml, { customHtml = await ClientHtml.addTags(customHtml, {
url, url,
originUrl, originUrl,
escapedSiteName: escapeHTML(siteName), escapedSiteName: escapeHTML(siteName),
@ -206,7 +212,7 @@ class ClientHtml {
ogType, ogType,
twitterCard, twitterCard,
schemaType schemaType
}) }, { playlist: videoPlaylist })
return customHtml return customHtml
} }
@ -290,7 +296,7 @@ class ClientHtml {
const twitterCard = 'summary' const twitterCard = 'summary'
const schemaType = 'ProfilePage' const schemaType = 'ProfilePage'
customHtml = ClientHtml.addTags(customHtml, { customHtml = await ClientHtml.addTags(customHtml, {
url, url,
originUrl, originUrl,
escapedTitle: escapeHTML(title), escapedTitle: escapeHTML(title),
@ -301,7 +307,7 @@ class ClientHtml {
twitterCard, twitterCard,
schemaType, schemaType,
disallowIndexation: !entity.Actor.isOwned() disallowIndexation: !entity.Actor.isOwned()
}) }, {})
return customHtml return customHtml
} }
@ -469,7 +475,7 @@ class ClientHtml {
return metaTags return metaTags
} }
private static generateSchemaTags (tags: Tags) { private static async generateSchemaTags (tags: Tags, context: HookContext) {
const schema = { const schema = {
'@context': 'http://schema.org', '@context': 'http://schema.org',
'@type': tags.schemaType, '@type': tags.schemaType,
@ -495,14 +501,14 @@ class ClientHtml {
schema['contentUrl'] = tags.url schema['contentUrl'] = tags.url
} }
return schema return Hooks.wrapObject(schema, 'filter:html.client.json-ld.result', context)
} }
private static addTags (htmlStringPage: string, tagsValues: Tags) { private static async addTags (htmlStringPage: string, tagsValues: Tags, context: HookContext) {
const openGraphMetaTags = this.generateOpenGraphMetaTags(tagsValues) const openGraphMetaTags = this.generateOpenGraphMetaTags(tagsValues)
const standardMetaTags = this.generateStandardMetaTags(tagsValues) const standardMetaTags = this.generateStandardMetaTags(tagsValues)
const twitterCardMetaTags = this.generateTwitterCardMetaTags(tagsValues) const twitterCardMetaTags = this.generateTwitterCardMetaTags(tagsValues)
const schemaTags = this.generateSchemaTags(tagsValues) const schemaTags = await this.generateSchemaTags(tagsValues, context)
const { url, escapedTitle, embed, originUrl, disallowIndexation } = tagsValues const { url, escapedTitle, embed, originUrl, disallowIndexation } = tagsValues

View File

@ -312,6 +312,8 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
} }
}) })
// ---------------------------------------------------------------------------
registerHook({ registerHook({
target: 'filter:html.embed.video.allowed.result', target: 'filter:html.embed.video.allowed.result',
handler: (result, params) => { handler: (result, params) => {
@ -332,6 +334,19 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
} }
}) })
// ---------------------------------------------------------------------------
registerHook({
target: 'filter:html.client.json-ld.result',
handler: (jsonld, context) => {
if (!context || !context.video) return jsonld
return Object.assign(jsonld, { recordedAt: 'http://example.com/recordedAt' })
}
})
// ---------------------------------------------------------------------------
registerHook({ registerHook({
target: 'filter:api.server.stats.get.result', target: 'filter:api.server.stats.get.result',
handler: (result) => { handler: (result) => {

View File

@ -605,6 +605,27 @@ describe('Test plugin filter hooks', function () {
}) })
}) })
describe('Client HTML filters', function () {
let videoUUID: string
before(async function () {
this.timeout(60000)
const { uuid } = await servers[0].videos.quickUpload({ name: 'html video' })
videoUUID = uuid
})
it('Should run filter:html.client.json-ld.result', async function () {
const res = await makeGetRequest({ url: servers[0].url, path: '/w/' + videoUUID, expectedStatus: HttpStatusCode.OK_200 })
expect(res.text).to.contain('"recordedAt":"http://example.com/recordedAt"')
})
it('Should not run filter:html.client.json-ld.result with an account', async function () {
const res = await makeGetRequest({ url: servers[0].url, path: '/a/root', expectedStatus: HttpStatusCode.OK_200 })
expect(res.text).not.to.contain('"recordedAt":"http://example.com/recordedAt"')
})
})
describe('Search filters', function () { describe('Search filters', function () {
before(async function () { before(async function () {

View File

@ -107,6 +107,8 @@ export const serverFilterHookObject = {
'filter:html.embed.video.allowed.result': true, 'filter:html.embed.video.allowed.result': true,
'filter:html.embed.video-playlist.allowed.result': true, 'filter:html.embed.video-playlist.allowed.result': true,
'filter:html.client.json-ld.result': true,
'filter:job-queue.process.params': true, 'filter:job-queue.process.params': true,
'filter:job-queue.process.result': true, 'filter:job-queue.process.result': true,