diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index 395cfa0d5..84828e7e0 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts @@ -335,10 +335,10 @@ async function videoRedundancyController (req: express.Request, res: express.Res if (req.path.endsWith('/activity')) { const data = buildCreateActivity(videoRedundancy.url, serverActor, object, audience) - return activityPubResponse(activityPubContextify(data), res) + return activityPubResponse(activityPubContextify(data, 'CacheFile'), res) } - return activityPubResponse(activityPubContextify(object), res) + return activityPubResponse(activityPubContextify(object, 'CacheFile'), res) } async function videoPlaylistController (req: express.Request, res: express.Response) { diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index 326785b68..2d49e6869 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts @@ -8,102 +8,117 @@ import { pageToStartAndCount } from './core-utils' import { URL } from 'url' import { MActor, MVideoAccountLight } from '../typings/models' -export type ContextType = 'All' | 'View' | 'Announce' +export type ContextType = 'All' | 'View' | 'Announce' | 'CacheFile' + +function getContextData (type: ContextType) { + const context: any[] = [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + { + RsaSignature2017: 'https://w3id.org/security#RsaSignature2017' + } + ] + + if (type !== 'View' && type !== 'Announce') { + const additional = { + pt: 'https://joinpeertube.org/ns#', + sc: 'http://schema.org#' + } + + if (type === 'CacheFile') { + Object.assign(additional, { + expires: 'sc:expires', + CacheFile: 'pt:CacheFile' + }) + } else { + Object.assign(additional, { + Hashtag: 'as:Hashtag', + uuid: 'sc:identifier', + category: 'sc:category', + licence: 'sc:license', + subtitleLanguage: 'sc:subtitleLanguage', + sensitive: 'as:sensitive', + language: 'sc:inLanguage', + + Infohash: 'pt:Infohash', + originallyPublishedAt: 'sc:datePublished', + views: { + '@type': 'sc:Number', + '@id': 'pt:views' + }, + state: { + '@type': 'sc:Number', + '@id': 'pt:state' + }, + size: { + '@type': 'sc:Number', + '@id': 'pt:size' + }, + fps: { + '@type': 'sc:Number', + '@id': 'pt:fps' + }, + startTimestamp: { + '@type': 'sc:Number', + '@id': 'pt:startTimestamp' + }, + stopTimestamp: { + '@type': 'sc:Number', + '@id': 'pt:stopTimestamp' + }, + position: { + '@type': 'sc:Number', + '@id': 'pt:position' + }, + commentsEnabled: { + '@type': 'sc:Boolean', + '@id': 'pt:commentsEnabled' + }, + downloadEnabled: { + '@type': 'sc:Boolean', + '@id': 'pt:downloadEnabled' + }, + waitTranscoding: { + '@type': 'sc:Boolean', + '@id': 'pt:waitTranscoding' + }, + support: { + '@type': 'sc:Text', + '@id': 'pt:support' + }, + likes: { + '@id': 'as:likes', + '@type': '@id' + }, + dislikes: { + '@id': 'as:dislikes', + '@type': '@id' + }, + playlists: { + '@id': 'pt:playlists', + '@type': '@id' + }, + shares: { + '@id': 'as:shares', + '@type': '@id' + }, + comments: { + '@id': 'as:comments', + '@type': '@id' + } + }) + } + + context.push(additional) + } + + return { + '@context': context + } +} function activityPubContextify (data: T, type: ContextType = 'All') { - const base = { - RsaSignature2017: 'https://w3id.org/security#RsaSignature2017' - } - - if (type === 'All') { - Object.assign(base, { - pt: 'https://joinpeertube.org/ns#', - sc: 'http://schema.org#', - Hashtag: 'as:Hashtag', - uuid: 'sc:identifier', - category: 'sc:category', - licence: 'sc:license', - subtitleLanguage: 'sc:subtitleLanguage', - sensitive: 'as:sensitive', - language: 'sc:inLanguage', - expires: 'sc:expires', - CacheFile: 'pt:CacheFile', - Infohash: 'pt:Infohash', - originallyPublishedAt: 'sc:datePublished', - views: { - '@type': 'sc:Number', - '@id': 'pt:views' - }, - state: { - '@type': 'sc:Number', - '@id': 'pt:state' - }, - size: { - '@type': 'sc:Number', - '@id': 'pt:size' - }, - fps: { - '@type': 'sc:Number', - '@id': 'pt:fps' - }, - startTimestamp: { - '@type': 'sc:Number', - '@id': 'pt:startTimestamp' - }, - stopTimestamp: { - '@type': 'sc:Number', - '@id': 'pt:stopTimestamp' - }, - position: { - '@type': 'sc:Number', - '@id': 'pt:position' - }, - commentsEnabled: { - '@type': 'sc:Boolean', - '@id': 'pt:commentsEnabled' - }, - downloadEnabled: { - '@type': 'sc:Boolean', - '@id': 'pt:downloadEnabled' - }, - waitTranscoding: { - '@type': 'sc:Boolean', - '@id': 'pt:waitTranscoding' - }, - support: { - '@type': 'sc:Text', - '@id': 'pt:support' - }, - likes: { - '@id': 'as:likes', - '@type': '@id' - }, - dislikes: { - '@id': 'as:dislikes', - '@type': '@id' - }, - playlists: { - '@id': 'pt:playlists', - '@type': '@id' - }, - shares: { - '@id': 'as:shares', - '@type': '@id' - }, - comments: { - '@id': 'as:comments', - '@type': '@id' - } - }) - } - - return Object.assign({}, data, { - '@context': [ - 'https://www.w3.org/ns/activitystreams', - 'https://w3id.org/security/v1', - base - ] - }) + return Object.assign({}, data, getContextData(type)) } type ActivityPubCollectionPaginationHandler = (start: number, count: number) => Bluebird> | Promise> diff --git a/server/lib/activitypub/send/send-create.ts b/server/lib/activitypub/send/send-create.ts index 3585d704a..8bdcf6417 100644 --- a/server/lib/activitypub/send/send-create.ts +++ b/server/lib/activitypub/send/send-create.ts @@ -16,6 +16,7 @@ import { MVideoRedundancyFileVideo, MVideoRedundancyStreamingPlaylistVideo } from '../../../typings/models' +import { ContextType } from '@server/helpers/activitypub' async function sendCreateVideo (video: MVideoAP, t: Transaction) { if (!video.hasPrivacyForFederation()) return undefined @@ -42,7 +43,8 @@ async function sendCreateCacheFile ( byActor, video, url: fileRedundancy.url, - object: fileRedundancy.toActivityPubObject() + object: fileRedundancy.toActivityPubObject(), + contextType: 'CacheFile' }) } @@ -135,6 +137,7 @@ async function sendVideoRelatedCreateActivity (options: { url: string object: any transaction?: Transaction + contextType?: ContextType }) { const activityBuilder = (audience: ActivityAudience) => { return buildCreateActivity(options.url, options.byActor, options.object, audience) diff --git a/server/lib/activitypub/send/send-update.ts b/server/lib/activitypub/send/send-update.ts index cb500bd34..2b01ca5e7 100644 --- a/server/lib/activitypub/send/send-update.ts +++ b/server/lib/activitypub/send/send-update.ts @@ -84,7 +84,7 @@ async function sendUpdateCacheFile (byActor: MActorLight, redundancyModel: MVide return buildUpdateActivity(url, byActor, redundancyObject, audience) } - return sendVideoRelatedActivity(activityBuilder, { byActor, video }) + return sendVideoRelatedActivity(activityBuilder, { byActor, video, contextType: 'CacheFile' }) } async function sendUpdateVideoPlaylist (videoPlaylist: MVideoPlaylistFull, t: Transaction) {