check_latest_versions_interval: '12 hours' # How often you want to check new plugins/themes versions
url: 'https://packages.joinpeertube.org'
+federation:
+ videos:
+ federate_unlisted: true
+
cache:
previews:
size: 500 # Max number of previews you want to cache
check_latest_versions_interval: '12 hours' # How often you want to check new plugins/themes versions
url: 'https://packages.joinpeertube.org'
+federation:
+ videos:
+ federate_unlisted: true
+
###############################################################################
#
import { Response } from 'express'
import { DEFAULT_AUDIO_RESOLUTION } from '@server/initializers/constants'
import { JobQueue } from '@server/lib/job-queue'
-import { VideoTranscodingPayload } from '@shared/models'
+import { VideoPrivacy, VideoTranscodingPayload } from '@shared/models'
+import { CONFIG } from "@server/initializers/config"
type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none' | 'only-immutable-attributes'
: videoOrPlaylist
}
+function isPrivacyForFederation (privacy: VideoPrivacy) {
+ const castedPrivacy = parseInt(privacy + '', 10)
+
+ return castedPrivacy === VideoPrivacy.PUBLIC ||
+ (CONFIG.FEDERATION.VIDEOS.FEDERATE_UNLISTED === true && castedPrivacy === VideoPrivacy.UNLISTED)
+}
+
+function getPrivaciesForFederation () {
+ return (CONFIG.FEDERATION.VIDEOS.FEDERATE_UNLISTED === true)
+ ? [ { privacy: VideoPrivacy.PUBLIC }, { privacy: VideoPrivacy.UNLISTED } ]
+ : [ { privacy: VideoPrivacy.PUBLIC } ]
+}
+
export {
VideoFetchType,
VideoFetchByUrlType,
getVideoWithAttributes,
fetchVideoByUrl,
addOptimizeOrMergeAudioJob,
- extractVideo
+ extractVideo,
+ isPrivacyForFederation,
+ getPrivaciesForFederation
}
'history.videos.max_age', 'views.videos.remote.max_age',
'rates_limit.login.window', 'rates_limit.login.max', 'rates_limit.ask_send_email.window', 'rates_limit.ask_send_email.max',
'theme.default',
- 'remote_redundancy.videos.accept_from'
+ 'remote_redundancy.videos.accept_from',
+ 'federation.videos.federate_unlisted'
]
const requiredAlternatives = [
[ // set
URL: config.get<string>('plugins.index.url')
}
},
+ FEDERATION: {
+ VIDEOS: {
+ FEDERATE_UNLISTED: config.get<boolean>('federation.videos.federate_unlisted')
+ }
+ },
ADMIN: {
get EMAIL () { return config.get<string>('admin.email') }
},
import { buildListQuery, BuildVideosQueryOptions, wrapForAPIResults } from './video-query-builder'
import { buildNSFWFilter } from '@server/helpers/express-utils'
import { getServerActor } from '@server/models/application/application'
+import { getPrivaciesForFederation, isPrivacyForFederation } from "@server/helpers/video"
export enum ScopeNames {
AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS',
id: {
[Op.in]: Sequelize.literal('(' + rawQuery + ')')
},
- [Op.or]: [
- { privacy: VideoPrivacy.PUBLIC },
- { privacy: VideoPrivacy.UNLISTED }
- ]
+ [Op.or]: getPrivaciesForFederation()
},
include: [
{
return videos
}
- private static isPrivacyForFederation (privacy: VideoPrivacy) {
- const castedPrivacy = parseInt(privacy + '', 10)
-
- return castedPrivacy === VideoPrivacy.PUBLIC || castedPrivacy === VideoPrivacy.UNLISTED
- }
-
static getCategoryLabel (id: number) {
return VIDEO_CATEGORIES[id] || 'Misc'
}
}
hasPrivacyForFederation () {
- return VideoModel.isPrivacyForFederation(this.privacy)
+ return isPrivacyForFederation(this.privacy)
}
isNewVideo (newPrivacy: VideoPrivacy) {
- return this.hasPrivacyForFederation() === false && VideoModel.isPrivacyForFederation(newPrivacy) === true
+ return this.hasPrivacyForFederation() === false && isPrivacyForFederation(newPrivacy) === true
}
setAsRefreshed () {
import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum'
import {
cleanupTests,
- flushAndRunMultipleServers,
+ flushAndRunServer,
getVideosList,
getVideosListWithToken,
ServerInfo,
const expect = chai.expect
describe('Test video privacy', function () {
- let servers: ServerInfo[] = []
+ const servers: ServerInfo[] = []
let anotherUserToken: string
let privateVideoId: number
let internalVideoUUID: string
let unlistedVideoUUID: string
+ let nonFederatedUnlistedVideoUUID: string
let now: number
+ const dontFederateUnlistedConfig = {
+ federation: {
+ videos: {
+ federate_unlisted: false
+ }
+ }
+ }
+
before(async function () {
this.timeout(50000)
// Run servers
- servers = await flushAndRunMultipleServers(2)
+ servers.push(await flushAndRunServer(1, dontFederateUnlistedConfig))
+ servers.push(await flushAndRunServer(2))
// Get the access tokens
await setAccessTokensToServers(servers)
}
})
+ it('Should upload a non-federating unlisted video to server 1', async function () {
+ this.timeout(30000)
+
+ const attributes = {
+ name: 'unlisted video',
+ privacy: VideoPrivacy.UNLISTED
+ }
+ await uploadVideo(servers[0].url, servers[0].accessToken, attributes)
+
+ await waitJobs(servers)
+ })
+
+ it('Should list my new unlisted video', async function () {
+ const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 3)
+
+ expect(res.body.total).to.equal(3)
+ expect(res.body.data).to.have.lengthOf(3)
+
+ nonFederatedUnlistedVideoUUID = res.body.data[0].uuid
+ })
+
+ it('Should be able to get non-federated unlisted video from origin', async function () {
+ const res = await getVideo(servers[0].url, nonFederatedUnlistedVideoUUID)
+
+ expect(res.body.name).to.equal('unlisted video')
+ })
+
+ it('Should not be able to get non-federated unlisted video from federated server', async function () {
+ await getVideo(servers[1].url, nonFederatedUnlistedVideoUUID, 404)
+ })
+
it('Should update the private and internal videos to public on server 1', async function () {
this.timeout(10000)
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 5)
const videos = res.body.data
- expect(res.body.total).to.equal(2)
- expect(videos).to.have.lengthOf(2)
+ expect(res.body.total).to.equal(3)
+ expect(videos).to.have.lengthOf(3)
const privateVideo = videos.find(v => v.name === 'private video becomes public')
const internalVideo = videos.find(v => v.name === 'internal video becomes public')