config.ts 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
  2. import { ActorImageType, CustomConfig, HttpStatusCode } from '@peertube/peertube-models'
  3. import { parallelTests } from '@peertube/peertube-node-utils'
  4. import {
  5. PeerTubeServer,
  6. cleanupTests,
  7. createSingleServer,
  8. killallServers,
  9. makeActivityPubGetRequest,
  10. makeGetRequest,
  11. makeRawRequest,
  12. setAccessTokensToServers
  13. } from '@peertube/peertube-server-commands'
  14. import { testAvatarSize, testFileExistsOnFSOrNot, testImage } from '@tests/shared/checks.js'
  15. import { expect } from 'chai'
  16. import { basename } from 'path'
  17. function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
  18. expect(data.instance.name).to.equal('PeerTube')
  19. expect(data.instance.shortDescription).to.equal(
  20. 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.'
  21. )
  22. expect(data.instance.description).to.equal('Welcome to this PeerTube instance!')
  23. expect(data.instance.terms).to.equal('No terms for now.')
  24. expect(data.instance.creationReason).to.be.empty
  25. expect(data.instance.codeOfConduct).to.be.empty
  26. expect(data.instance.moderationInformation).to.be.empty
  27. expect(data.instance.administrator).to.be.empty
  28. expect(data.instance.maintenanceLifetime).to.be.empty
  29. expect(data.instance.businessModel).to.be.empty
  30. expect(data.instance.hardwareInformation).to.be.empty
  31. expect(data.instance.languages).to.have.lengthOf(0)
  32. expect(data.instance.categories).to.have.lengthOf(0)
  33. expect(data.instance.defaultClientRoute).to.equal('/videos/trending')
  34. expect(data.instance.isNSFW).to.be.false
  35. expect(data.instance.defaultNSFWPolicy).to.equal('display')
  36. expect(data.instance.customizations.css).to.be.empty
  37. expect(data.instance.customizations.javascript).to.be.empty
  38. expect(data.services.twitter.username).to.equal('@Chocobozzz')
  39. expect(data.client.videos.miniature.preferAuthorDisplayName).to.be.false
  40. expect(data.client.menu.login.redirectOnSingleExternalAuth).to.be.false
  41. expect(data.cache.previews.size).to.equal(1)
  42. expect(data.cache.captions.size).to.equal(1)
  43. expect(data.cache.torrents.size).to.equal(1)
  44. expect(data.cache.storyboards.size).to.equal(1)
  45. expect(data.signup.enabled).to.be.true
  46. expect(data.signup.limit).to.equal(4)
  47. expect(data.signup.minimumAge).to.equal(16)
  48. expect(data.signup.requiresApproval).to.be.false
  49. expect(data.signup.requiresEmailVerification).to.be.false
  50. expect(data.admin.email).to.equal('admin' + server.internalServerNumber + '@example.com')
  51. expect(data.contactForm.enabled).to.be.true
  52. expect(data.user.history.videos.enabled).to.be.true
  53. expect(data.user.videoQuota).to.equal(5242880)
  54. expect(data.user.videoQuotaDaily).to.equal(-1)
  55. expect(data.videoChannels.maxPerUser).to.equal(20)
  56. expect(data.transcoding.enabled).to.be.false
  57. expect(data.transcoding.remoteRunners.enabled).to.be.false
  58. expect(data.transcoding.allowAdditionalExtensions).to.be.false
  59. expect(data.transcoding.allowAudioFiles).to.be.false
  60. expect(data.transcoding.threads).to.equal(2)
  61. expect(data.transcoding.concurrency).to.equal(2)
  62. expect(data.transcoding.profile).to.equal('default')
  63. expect(data.transcoding.resolutions['144p']).to.be.false
  64. expect(data.transcoding.resolutions['240p']).to.be.true
  65. expect(data.transcoding.resolutions['360p']).to.be.true
  66. expect(data.transcoding.resolutions['480p']).to.be.true
  67. expect(data.transcoding.resolutions['720p']).to.be.true
  68. expect(data.transcoding.resolutions['1080p']).to.be.true
  69. expect(data.transcoding.resolutions['1440p']).to.be.true
  70. expect(data.transcoding.resolutions['2160p']).to.be.true
  71. expect(data.transcoding.alwaysTranscodeOriginalResolution).to.be.true
  72. expect(data.transcoding.webVideos.enabled).to.be.true
  73. expect(data.transcoding.hls.enabled).to.be.true
  74. expect(data.transcoding.originalFile.keep).to.be.false
  75. expect(data.live.enabled).to.be.false
  76. expect(data.live.allowReplay).to.be.false
  77. expect(data.live.latencySetting.enabled).to.be.true
  78. expect(data.live.maxDuration).to.equal(-1)
  79. expect(data.live.maxInstanceLives).to.equal(20)
  80. expect(data.live.maxUserLives).to.equal(3)
  81. expect(data.live.transcoding.enabled).to.be.false
  82. expect(data.live.transcoding.remoteRunners.enabled).to.be.false
  83. expect(data.live.transcoding.threads).to.equal(2)
  84. expect(data.live.transcoding.profile).to.equal('default')
  85. expect(data.live.transcoding.resolutions['144p']).to.be.false
  86. expect(data.live.transcoding.resolutions['240p']).to.be.false
  87. expect(data.live.transcoding.resolutions['360p']).to.be.false
  88. expect(data.live.transcoding.resolutions['480p']).to.be.false
  89. expect(data.live.transcoding.resolutions['720p']).to.be.false
  90. expect(data.live.transcoding.resolutions['1080p']).to.be.false
  91. expect(data.live.transcoding.resolutions['1440p']).to.be.false
  92. expect(data.live.transcoding.resolutions['2160p']).to.be.false
  93. expect(data.live.transcoding.alwaysTranscodeOriginalResolution).to.be.true
  94. expect(data.videoStudio.enabled).to.be.false
  95. expect(data.videoStudio.remoteRunners.enabled).to.be.false
  96. expect(data.videoFile.update.enabled).to.be.false
  97. expect(data.import.videos.concurrency).to.equal(2)
  98. expect(data.import.videos.http.enabled).to.be.true
  99. expect(data.import.videos.torrent.enabled).to.be.true
  100. expect(data.import.videoChannelSynchronization.enabled).to.be.false
  101. expect(data.import.users.enabled).to.be.true
  102. expect(data.autoBlacklist.videos.ofUsers.enabled).to.be.false
  103. expect(data.followers.instance.enabled).to.be.true
  104. expect(data.followers.instance.manualApproval).to.be.false
  105. expect(data.followings.instance.autoFollowBack.enabled).to.be.false
  106. expect(data.followings.instance.autoFollowIndex.enabled).to.be.false
  107. expect(data.followings.instance.autoFollowIndex.indexUrl).to.equal('')
  108. expect(data.broadcastMessage.enabled).to.be.false
  109. expect(data.broadcastMessage.level).to.equal('info')
  110. expect(data.broadcastMessage.message).to.equal('')
  111. expect(data.broadcastMessage.dismissable).to.be.false
  112. expect(data.storyboards.enabled).to.be.true
  113. expect(data.export.users.enabled).to.be.true
  114. expect(data.export.users.exportExpiration).to.equal(1000 * 3600 * 48)
  115. expect(data.export.users.maxUserVideoQuota).to.equal(10737418240)
  116. }
  117. function checkUpdatedConfig (data: CustomConfig) {
  118. expect(data.instance.name).to.equal('PeerTube updated')
  119. expect(data.instance.shortDescription).to.equal('my short description')
  120. expect(data.instance.description).to.equal('my super description')
  121. expect(data.instance.terms).to.equal('my super terms')
  122. expect(data.instance.creationReason).to.equal('my super creation reason')
  123. expect(data.instance.codeOfConduct).to.equal('my super coc')
  124. expect(data.instance.moderationInformation).to.equal('my super moderation information')
  125. expect(data.instance.administrator).to.equal('Kuja')
  126. expect(data.instance.maintenanceLifetime).to.equal('forever')
  127. expect(data.instance.businessModel).to.equal('my super business model')
  128. expect(data.instance.hardwareInformation).to.equal('2vCore 3GB RAM')
  129. expect(data.instance.languages).to.deep.equal([ 'en', 'es' ])
  130. expect(data.instance.categories).to.deep.equal([ 1, 2 ])
  131. expect(data.instance.defaultClientRoute).to.equal('/videos/recently-added')
  132. expect(data.instance.isNSFW).to.be.true
  133. expect(data.instance.defaultNSFWPolicy).to.equal('blur')
  134. expect(data.instance.customizations.javascript).to.equal('alert("coucou")')
  135. expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
  136. expect(data.services.twitter.username).to.equal('@Kuja')
  137. expect(data.client.videos.miniature.preferAuthorDisplayName).to.be.true
  138. expect(data.client.menu.login.redirectOnSingleExternalAuth).to.be.true
  139. expect(data.cache.previews.size).to.equal(2)
  140. expect(data.cache.captions.size).to.equal(3)
  141. expect(data.cache.torrents.size).to.equal(4)
  142. expect(data.cache.storyboards.size).to.equal(5)
  143. expect(data.signup.enabled).to.be.false
  144. expect(data.signup.limit).to.equal(5)
  145. expect(data.signup.requiresApproval).to.be.false
  146. expect(data.signup.requiresEmailVerification).to.be.false
  147. expect(data.signup.minimumAge).to.equal(10)
  148. // We override admin email in parallel tests, so skip this exception
  149. if (parallelTests() === false) {
  150. expect(data.admin.email).to.equal('superadmin1@example.com')
  151. }
  152. expect(data.contactForm.enabled).to.be.false
  153. expect(data.user.history.videos.enabled).to.be.false
  154. expect(data.user.videoQuota).to.equal(5242881)
  155. expect(data.user.videoQuotaDaily).to.equal(318742)
  156. expect(data.videoChannels.maxPerUser).to.equal(24)
  157. expect(data.transcoding.enabled).to.be.true
  158. expect(data.transcoding.remoteRunners.enabled).to.be.true
  159. expect(data.transcoding.threads).to.equal(1)
  160. expect(data.transcoding.concurrency).to.equal(3)
  161. expect(data.transcoding.allowAdditionalExtensions).to.be.true
  162. expect(data.transcoding.allowAudioFiles).to.be.true
  163. expect(data.transcoding.profile).to.equal('vod_profile')
  164. expect(data.transcoding.resolutions['144p']).to.be.false
  165. expect(data.transcoding.resolutions['240p']).to.be.false
  166. expect(data.transcoding.resolutions['360p']).to.be.true
  167. expect(data.transcoding.resolutions['480p']).to.be.true
  168. expect(data.transcoding.resolutions['720p']).to.be.false
  169. expect(data.transcoding.resolutions['1080p']).to.be.false
  170. expect(data.transcoding.resolutions['2160p']).to.be.false
  171. expect(data.transcoding.alwaysTranscodeOriginalResolution).to.be.false
  172. expect(data.transcoding.hls.enabled).to.be.false
  173. expect(data.transcoding.webVideos.enabled).to.be.true
  174. expect(data.transcoding.originalFile.keep).to.be.true
  175. expect(data.live.enabled).to.be.true
  176. expect(data.live.allowReplay).to.be.true
  177. expect(data.live.latencySetting.enabled).to.be.false
  178. expect(data.live.maxDuration).to.equal(5000)
  179. expect(data.live.maxInstanceLives).to.equal(-1)
  180. expect(data.live.maxUserLives).to.equal(10)
  181. expect(data.live.transcoding.enabled).to.be.true
  182. expect(data.live.transcoding.remoteRunners.enabled).to.be.true
  183. expect(data.live.transcoding.threads).to.equal(4)
  184. expect(data.live.transcoding.profile).to.equal('live_profile')
  185. expect(data.live.transcoding.resolutions['144p']).to.be.true
  186. expect(data.live.transcoding.resolutions['240p']).to.be.true
  187. expect(data.live.transcoding.resolutions['360p']).to.be.true
  188. expect(data.live.transcoding.resolutions['480p']).to.be.true
  189. expect(data.live.transcoding.resolutions['720p']).to.be.true
  190. expect(data.live.transcoding.resolutions['1080p']).to.be.true
  191. expect(data.live.transcoding.resolutions['2160p']).to.be.true
  192. expect(data.live.transcoding.alwaysTranscodeOriginalResolution).to.be.false
  193. expect(data.videoStudio.enabled).to.be.true
  194. expect(data.videoStudio.remoteRunners.enabled).to.be.true
  195. expect(data.videoFile.update.enabled).to.be.true
  196. expect(data.import.videos.concurrency).to.equal(4)
  197. expect(data.import.videos.http.enabled).to.be.false
  198. expect(data.import.videos.torrent.enabled).to.be.false
  199. expect(data.import.videoChannelSynchronization.enabled).to.be.false
  200. expect(data.import.users.enabled).to.be.false
  201. expect(data.autoBlacklist.videos.ofUsers.enabled).to.be.true
  202. expect(data.followers.instance.enabled).to.be.false
  203. expect(data.followers.instance.manualApproval).to.be.true
  204. expect(data.followings.instance.autoFollowBack.enabled).to.be.true
  205. expect(data.followings.instance.autoFollowIndex.enabled).to.be.true
  206. expect(data.followings.instance.autoFollowIndex.indexUrl).to.equal('https://updated.example.com')
  207. expect(data.broadcastMessage.enabled).to.be.true
  208. expect(data.broadcastMessage.level).to.equal('error')
  209. expect(data.broadcastMessage.message).to.equal('super bad message')
  210. expect(data.broadcastMessage.dismissable).to.be.true
  211. expect(data.storyboards.enabled).to.be.false
  212. expect(data.export.users.enabled).to.be.false
  213. expect(data.export.users.exportExpiration).to.equal(43)
  214. expect(data.export.users.maxUserVideoQuota).to.equal(42)
  215. }
  216. const newCustomConfig: CustomConfig = {
  217. instance: {
  218. name: 'PeerTube updated',
  219. shortDescription: 'my short description',
  220. description: 'my super description',
  221. terms: 'my super terms',
  222. codeOfConduct: 'my super coc',
  223. creationReason: 'my super creation reason',
  224. moderationInformation: 'my super moderation information',
  225. administrator: 'Kuja',
  226. maintenanceLifetime: 'forever',
  227. businessModel: 'my super business model',
  228. hardwareInformation: '2vCore 3GB RAM',
  229. languages: [ 'en', 'es' ],
  230. categories: [ 1, 2 ],
  231. isNSFW: true,
  232. defaultNSFWPolicy: 'blur' as 'blur',
  233. defaultClientRoute: '/videos/recently-added',
  234. customizations: {
  235. javascript: 'alert("coucou")',
  236. css: 'body { background-color: red; }'
  237. }
  238. },
  239. theme: {
  240. default: 'default'
  241. },
  242. services: {
  243. twitter: {
  244. username: '@Kuja'
  245. }
  246. },
  247. client: {
  248. videos: {
  249. miniature: {
  250. preferAuthorDisplayName: true
  251. }
  252. },
  253. menu: {
  254. login: {
  255. redirectOnSingleExternalAuth: true
  256. }
  257. }
  258. },
  259. cache: {
  260. previews: {
  261. size: 2
  262. },
  263. captions: {
  264. size: 3
  265. },
  266. torrents: {
  267. size: 4
  268. },
  269. storyboards: {
  270. size: 5
  271. }
  272. },
  273. signup: {
  274. enabled: false,
  275. limit: 5,
  276. requiresApproval: false,
  277. requiresEmailVerification: false,
  278. minimumAge: 10
  279. },
  280. admin: {
  281. email: 'superadmin1@example.com'
  282. },
  283. contactForm: {
  284. enabled: false
  285. },
  286. user: {
  287. history: {
  288. videos: {
  289. enabled: false
  290. }
  291. },
  292. videoQuota: 5242881,
  293. videoQuotaDaily: 318742,
  294. defaultChannelName: 'Main $1 channel'
  295. },
  296. videoChannels: {
  297. maxPerUser: 24
  298. },
  299. transcoding: {
  300. enabled: true,
  301. remoteRunners: {
  302. enabled: true
  303. },
  304. originalFile: {
  305. keep: true
  306. },
  307. allowAdditionalExtensions: true,
  308. allowAudioFiles: true,
  309. threads: 1,
  310. concurrency: 3,
  311. profile: 'vod_profile',
  312. resolutions: {
  313. '0p': false,
  314. '144p': false,
  315. '240p': false,
  316. '360p': true,
  317. '480p': true,
  318. '720p': false,
  319. '1080p': false,
  320. '1440p': false,
  321. '2160p': false
  322. },
  323. alwaysTranscodeOriginalResolution: false,
  324. webVideos: {
  325. enabled: true
  326. },
  327. hls: {
  328. enabled: false
  329. }
  330. },
  331. live: {
  332. enabled: true,
  333. allowReplay: true,
  334. latencySetting: {
  335. enabled: false
  336. },
  337. maxDuration: 5000,
  338. maxInstanceLives: -1,
  339. maxUserLives: 10,
  340. transcoding: {
  341. enabled: true,
  342. remoteRunners: {
  343. enabled: true
  344. },
  345. threads: 4,
  346. profile: 'live_profile',
  347. resolutions: {
  348. '144p': true,
  349. '240p': true,
  350. '360p': true,
  351. '480p': true,
  352. '720p': true,
  353. '1080p': true,
  354. '1440p': true,
  355. '2160p': true
  356. },
  357. alwaysTranscodeOriginalResolution: false
  358. }
  359. },
  360. videoStudio: {
  361. enabled: true,
  362. remoteRunners: {
  363. enabled: true
  364. }
  365. },
  366. videoFile: {
  367. update: {
  368. enabled: true
  369. }
  370. },
  371. import: {
  372. videos: {
  373. concurrency: 4,
  374. http: {
  375. enabled: false
  376. },
  377. torrent: {
  378. enabled: false
  379. }
  380. },
  381. videoChannelSynchronization: {
  382. enabled: false,
  383. maxPerUser: 10
  384. },
  385. users: {
  386. enabled: false
  387. }
  388. },
  389. trending: {
  390. videos: {
  391. algorithms: {
  392. enabled: [ 'hot', 'most-viewed', 'most-liked' ],
  393. default: 'hot'
  394. }
  395. }
  396. },
  397. autoBlacklist: {
  398. videos: {
  399. ofUsers: {
  400. enabled: true
  401. }
  402. }
  403. },
  404. followers: {
  405. instance: {
  406. enabled: false,
  407. manualApproval: true
  408. }
  409. },
  410. followings: {
  411. instance: {
  412. autoFollowBack: {
  413. enabled: true
  414. },
  415. autoFollowIndex: {
  416. enabled: true,
  417. indexUrl: 'https://updated.example.com'
  418. }
  419. }
  420. },
  421. broadcastMessage: {
  422. enabled: true,
  423. level: 'error',
  424. message: 'super bad message',
  425. dismissable: true
  426. },
  427. search: {
  428. remoteUri: {
  429. anonymous: true,
  430. users: true
  431. },
  432. searchIndex: {
  433. enabled: true,
  434. url: 'https://search.joinpeertube.org',
  435. disableLocalSearch: true,
  436. isDefaultSearch: true
  437. }
  438. },
  439. storyboards: {
  440. enabled: false
  441. },
  442. export: {
  443. users: {
  444. enabled: false,
  445. exportExpiration: 43,
  446. maxUserVideoQuota: 42
  447. }
  448. }
  449. }
  450. describe('Test static config', function () {
  451. let server: PeerTubeServer = null
  452. before(async function () {
  453. this.timeout(30000)
  454. server = await createSingleServer(1, { webadmin: { configuration: { edition: { allowed: false } } } })
  455. await setAccessTokensToServers([ server ])
  456. })
  457. it('Should tell the client that edits are not allowed', async function () {
  458. const data = await server.config.getConfig()
  459. expect(data.webadmin.configuration.edition.allowed).to.be.false
  460. })
  461. it('Should error when client tries to update', async function () {
  462. await server.config.updateCustomConfig({ newCustomConfig, expectedStatus: 405 })
  463. })
  464. after(async function () {
  465. await cleanupTests([ server ])
  466. })
  467. })
  468. describe('Test config', function () {
  469. let server: PeerTubeServer
  470. before(async function () {
  471. this.timeout(30000)
  472. server = await createSingleServer(1)
  473. await setAccessTokensToServers([ server ])
  474. })
  475. describe('Config keys', function () {
  476. it('Should have the correct default config', async function () {
  477. const data = await server.config.getConfig()
  478. expect(data.openTelemetry.metrics.enabled).to.be.false
  479. expect(data.openTelemetry.metrics.playbackStatsInterval).to.equal(15000)
  480. expect(data.views.videos.watchingInterval.anonymous).to.equal(5000)
  481. expect(data.views.videos.watchingInterval.users).to.equal(5000)
  482. })
  483. it('Should have a correct config on a server with registration enabled', async function () {
  484. const data = await server.config.getConfig()
  485. expect(data.signup.allowed).to.be.true
  486. })
  487. it('Should have a correct config on a server with registration enabled and a users limit', async function () {
  488. this.timeout(5000)
  489. await Promise.all([
  490. server.registrations.register({ username: 'user1' }),
  491. server.registrations.register({ username: 'user2' }),
  492. server.registrations.register({ username: 'user3' })
  493. ])
  494. const data = await server.config.getConfig()
  495. expect(data.signup.allowed).to.be.false
  496. })
  497. it('Should have the correct video allowed extensions', async function () {
  498. const data = await server.config.getConfig()
  499. expect(data.video.file.extensions).to.have.lengthOf(3)
  500. expect(data.video.file.extensions).to.contain('.mp4')
  501. expect(data.video.file.extensions).to.contain('.webm')
  502. expect(data.video.file.extensions).to.contain('.ogv')
  503. await server.videos.upload({ attributes: { fixture: 'video_short.mkv' }, expectedStatus: HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415 })
  504. await server.videos.upload({ attributes: { fixture: 'sample.ogg' }, expectedStatus: HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415 })
  505. expect(data.contactForm.enabled).to.be.true
  506. })
  507. it('Should get the customized configuration', async function () {
  508. const data = await server.config.getCustomConfig()
  509. checkInitialConfig(server, data)
  510. })
  511. it('Should update the customized configuration', async function () {
  512. await server.config.updateCustomConfig({ newCustomConfig })
  513. const data = await server.config.getCustomConfig()
  514. checkUpdatedConfig(data)
  515. })
  516. it('Should have the correct updated video allowed extensions', async function () {
  517. this.timeout(30000)
  518. const data = await server.config.getConfig()
  519. expect(data.video.file.extensions).to.have.length.above(4)
  520. expect(data.video.file.extensions).to.contain('.mp4')
  521. expect(data.video.file.extensions).to.contain('.webm')
  522. expect(data.video.file.extensions).to.contain('.ogv')
  523. expect(data.video.file.extensions).to.contain('.flv')
  524. expect(data.video.file.extensions).to.contain('.wmv')
  525. expect(data.video.file.extensions).to.contain('.mkv')
  526. expect(data.video.file.extensions).to.contain('.mp3')
  527. expect(data.video.file.extensions).to.contain('.ogg')
  528. expect(data.video.file.extensions).to.contain('.flac')
  529. await server.videos.upload({ attributes: { fixture: 'video_short.mkv' }, expectedStatus: HttpStatusCode.OK_200 })
  530. await server.videos.upload({ attributes: { fixture: 'sample.ogg' }, expectedStatus: HttpStatusCode.OK_200 })
  531. })
  532. it('Should have the configuration updated after a restart', async function () {
  533. this.timeout(30000)
  534. await killallServers([ server ])
  535. await server.run()
  536. const data = await server.config.getCustomConfig()
  537. checkUpdatedConfig(data)
  538. })
  539. it('Should fetch the about information', async function () {
  540. const { instance } = await server.config.getAbout()
  541. expect(instance.name).to.equal('PeerTube updated')
  542. expect(instance.shortDescription).to.equal('my short description')
  543. expect(instance.description).to.equal('my super description')
  544. expect(instance.terms).to.equal('my super terms')
  545. expect(instance.codeOfConduct).to.equal('my super coc')
  546. expect(instance.creationReason).to.equal('my super creation reason')
  547. expect(instance.moderationInformation).to.equal('my super moderation information')
  548. expect(instance.administrator).to.equal('Kuja')
  549. expect(instance.maintenanceLifetime).to.equal('forever')
  550. expect(instance.businessModel).to.equal('my super business model')
  551. expect(instance.hardwareInformation).to.equal('2vCore 3GB RAM')
  552. expect(instance.languages).to.deep.equal([ 'en', 'es' ])
  553. expect(instance.categories).to.deep.equal([ 1, 2 ])
  554. expect(instance.banners).to.have.lengthOf(0)
  555. })
  556. it('Should remove the custom configuration', async function () {
  557. await server.config.deleteCustomConfig()
  558. const data = await server.config.getCustomConfig()
  559. checkInitialConfig(server, data)
  560. })
  561. it('Should enable/disable security headers', async function () {
  562. this.timeout(25000)
  563. {
  564. const res = await makeGetRequest({
  565. url: server.url,
  566. path: '/api/v1/config',
  567. expectedStatus: 200
  568. })
  569. expect(res.headers['x-frame-options']).to.exist
  570. expect(res.headers['x-powered-by']).to.equal('PeerTube')
  571. }
  572. await killallServers([ server ])
  573. const config = {
  574. security: {
  575. frameguard: { enabled: false },
  576. powered_by_header: { enabled: false }
  577. }
  578. }
  579. await server.run(config)
  580. {
  581. const res = await makeGetRequest({
  582. url: server.url,
  583. path: '/api/v1/config',
  584. expectedStatus: 200
  585. })
  586. expect(res.headers['x-frame-options']).to.not.exist
  587. expect(res.headers['x-powered-by']).to.not.exist
  588. }
  589. })
  590. })
  591. describe('Image files', function () {
  592. async function checkAndGetServerImages () {
  593. const { instance } = await server.config.getAbout()
  594. const htmlConfig = await server.config.getConfig()
  595. expect(instance.avatars).to.deep.equal(htmlConfig.instance.avatars)
  596. expect(instance.banners).to.deep.equal(htmlConfig.instance.banners)
  597. return htmlConfig.instance
  598. }
  599. describe('Banner', function () {
  600. const bannerPaths: string[] = []
  601. it('Should update instance banner', async function () {
  602. await server.config.updateInstanceImage({ type: ActorImageType.BANNER, fixture: 'banner.jpg' })
  603. const { banners } = await checkAndGetServerImages()
  604. expect(banners).to.have.lengthOf(2)
  605. for (const banner of banners) {
  606. await testImage(server.url, `banner-resized-${banner.width}`, banner.path)
  607. await testFileExistsOnFSOrNot(server, 'avatars', basename(banner.path), true)
  608. bannerPaths.push(banner.path)
  609. }
  610. })
  611. it('Should re-update an existing instance banner', async function () {
  612. await server.config.updateInstanceImage({ type: ActorImageType.BANNER, fixture: 'banner.jpg' })
  613. })
  614. it('Should remove instance banner', async function () {
  615. await server.config.deleteInstanceImage({ type: ActorImageType.BANNER })
  616. const { banners } = await checkAndGetServerImages()
  617. expect(banners).to.have.lengthOf(0)
  618. for (const bannerPath of bannerPaths) {
  619. await testFileExistsOnFSOrNot(server, 'avatars', basename(bannerPath), false)
  620. }
  621. })
  622. })
  623. describe('Avatar', function () {
  624. const avatarPaths: string[] = []
  625. it('Should update instance avatar', async function () {
  626. for (const extension of [ '.png', '.gif' ]) {
  627. const fixture = 'avatar' + extension
  628. await server.config.updateInstanceImage({ type: ActorImageType.AVATAR, fixture })
  629. const { avatars } = await checkAndGetServerImages()
  630. for (const avatar of avatars) {
  631. await testAvatarSize({ url: server.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` })
  632. await testFileExistsOnFSOrNot(server, 'avatars', basename(avatar.path), true)
  633. avatarPaths.push(avatar.path)
  634. }
  635. }
  636. })
  637. it('Should have the avatars in the AP representation of the instance', async function () {
  638. const res = await makeActivityPubGetRequest(server.url, '/accounts/peertube')
  639. const object = res.body
  640. expect(object.icon).to.have.lengthOf(4)
  641. for (const icon of object.icon) {
  642. await makeRawRequest({ url: icon.url, expectedStatus: HttpStatusCode.OK_200 })
  643. }
  644. })
  645. it('Should remove instance avatar', async function () {
  646. await server.config.deleteInstanceImage({ type: ActorImageType.AVATAR })
  647. const { avatars } = await checkAndGetServerImages()
  648. expect(avatars).to.have.lengthOf(0)
  649. for (const avatarPath of avatarPaths) {
  650. await testFileExistsOnFSOrNot(server, 'avatars', basename(avatarPath), false)
  651. }
  652. })
  653. it('Should not have the avatars anymore in the AP representation of the instance', async function () {
  654. const res = await makeActivityPubGetRequest(server.url, '/accounts/peertube')
  655. const object = res.body
  656. expect(object.icon).to.not.exist
  657. })
  658. })
  659. })
  660. after(async function () {
  661. await cleanupTests([ server ])
  662. })
  663. })