Browse Source

Move config in its own file

tags/v1.3.0-rc.1
Chocobozzz 4 years ago
parent
commit
6dd9de95df
No known key found for this signature in database GPG Key ID: 583A612D890159BE
79 changed files with 523 additions and 458 deletions
  1. +8
    -11
      server/controllers/activitypub/client.ts
  2. +2
    -1
      server/controllers/api/config.ts
  3. +1
    -1
      server/controllers/api/oauth-clients.ts
  4. +2
    -1
      server/controllers/api/server/logs.ts
  5. +2
    -1
      server/controllers/api/server/stats.ts
  6. +4
    -3
      server/controllers/api/users/index.ts
  7. +2
    -1
      server/controllers/api/users/me.ts
  8. +2
    -2
      server/controllers/api/users/my-subscriptions.ts
  9. +2
    -1
      server/controllers/api/video-channel.ts
  10. +2
    -1
      server/controllers/api/video-playlist.ts
  11. +2
    -1
      server/controllers/api/videos/captions.ts
  12. +3
    -2
      server/controllers/api/videos/import.ts
  13. +1
    -1
      server/controllers/api/videos/index.ts
  14. +8
    -8
      server/controllers/bots.ts
  15. +6
    -5
      server/controllers/feeds.ts
  16. +3
    -3
      server/controllers/services.ts
  17. +4
    -3
      server/controllers/static.ts
  18. +2
    -1
      server/controllers/tracker.ts
  19. +1
    -1
      server/helpers/audit-logger.ts
  20. +1
    -1
      server/helpers/captions-utils.ts
  21. +1
    -1
      server/helpers/custom-validators/video-channels.ts
  22. +2
    -2
      server/helpers/custom-validators/webfinger.ts
  23. +3
    -2
      server/helpers/express-utils.ts
  24. +3
    -2
      server/helpers/ffmpeg-utils.ts
  25. +1
    -1
      server/helpers/logger.ts
  26. +2
    -1
      server/helpers/requests.ts
  27. +2
    -1
      server/helpers/signup.ts
  28. +1
    -1
      server/helpers/utils.ts
  29. +2
    -2
      server/helpers/webfinger.ts
  30. +1
    -1
      server/helpers/webtorrent.ts
  31. +3
    -2
      server/initializers/checker-after-init.ts
  32. +255
    -0
      server/initializers/config.ts
  33. +51
    -270
      server/initializers/constants.ts
  34. +1
    -1
      server/initializers/database.ts
  35. +3
    -2
      server/initializers/installer.ts
  36. +1
    -1
      server/initializers/migrations/0075-video-resolutions.ts
  37. +3
    -3
      server/initializers/migrations/0140-actor-url.ts
  38. +0
    -4
      server/initializers/migrations/0235-delete-some-video-indexes.ts
  39. +0
    -4
      server/initializers/migrations/0240-drop-old-indexes.ts
  40. +2
    -2
      server/initializers/migrations/0345-video-playlists.ts
  41. +3
    -2
      server/lib/activitypub/actor.ts
  42. +2
    -1
      server/lib/activitypub/playlist.ts
  43. +2
    -1
      server/lib/activitypub/process/process-follow.ts
  44. +10
    -10
      server/lib/activitypub/url.ts
  45. +1
    -1
      server/lib/activitypub/videos.ts
  46. +2
    -1
      server/lib/avatar.ts
  47. +7
    -6
      server/lib/client-html.ts
  48. +22
    -21
      server/lib/emailer.ts
  49. +2
    -1
      server/lib/files-cache/videos-caption-cache.ts
  50. +2
    -1
      server/lib/files-cache/videos-preview-cache.ts
  51. +2
    -1
      server/lib/hls.ts
  52. +2
    -2
      server/lib/job-queue/handlers/activitypub-follow.ts
  53. +3
    -2
      server/lib/job-queue/handlers/video-import.ts
  54. +2
    -1
      server/lib/job-queue/handlers/video-transcoding.ts
  55. +2
    -2
      server/lib/job-queue/job-queue.ts
  56. +1
    -1
      server/lib/notifier.ts
  57. +2
    -1
      server/lib/oauth-model.ts
  58. +4
    -3
      server/lib/redis.ts
  59. +4
    -3
      server/lib/schedulers/videos-redundancy-scheduler.ts
  60. +1
    -1
      server/lib/video-blacklist.ts
  61. +4
    -3
      server/lib/video-transcoding.ts
  62. +1
    -1
      server/middlewares/csp.ts
  63. +2
    -3
      server/middlewares/validators/blocklist.ts
  64. +2
    -2
      server/middlewares/validators/follows.ts
  65. +2
    -2
      server/middlewares/validators/oembed.ts
  66. +1
    -1
      server/middlewares/validators/server.ts
  67. +2
    -2
      server/middlewares/validators/user-subscriptions.ts
  68. +1
    -1
      server/middlewares/validators/videos/video-imports.ts
  69. +2
    -1
      server/middlewares/validators/videos/videos.ts
  70. +2
    -2
      server/models/account/account.ts
  71. +3
    -3
      server/models/activitypub/actor.ts
  72. +2
    -1
      server/models/avatar/avatar.ts
  73. +2
    -1
      server/models/redundancy/video-redundancy.ts
  74. +2
    -1
      server/models/video/video-caption.ts
  75. +4
    -3
      server/models/video/video-channel.ts
  76. +2
    -2
      server/models/video/video-comment.ts
  77. +2
    -2
      server/models/video/video-format-utils.ts
  78. +4
    -3
      server/models/video/video-playlist.ts
  79. +12
    -10
      server/models/video/video.ts

+ 8
- 11
server/controllers/activitypub/client.ts View File

@@ -2,7 +2,7 @@
import * as express from 'express'
import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos'
import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub'
import { CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers'
import { ROUTE_CACHE_LIFETIME, WEBSERVER } from '../../initializers'
import { buildAnnounceWithVideoAudience, buildLikeActivity } from '../../lib/activitypub/send'
import { audiencify, getAudience } from '../../lib/activitypub/audience'
import { buildCreateActivity } from '../../lib/activitypub/send/send-create'
@@ -19,7 +19,6 @@ import { AccountModel } from '../../models/account/account'
import { ActorModel } from '../../models/activitypub/actor'
import { ActorFollowModel } from '../../models/activitypub/actor-follow'
import { VideoModel } from '../../models/video/video'
import { VideoChannelModel } from '../../models/video/video-channel'
import { VideoCommentModel } from '../../models/video/video-comment'
import { VideoShareModel } from '../../models/video/video-share'
import { cacheRoute } from '../../middlewares/cache'
@@ -35,11 +34,9 @@ import {
import { VideoCaptionModel } from '../../models/video/video-caption'
import { videoFileRedundancyGetValidator, videoPlaylistRedundancyGetValidator } from '../../middlewares/validators/redundancy'
import { getServerActor } from '../../helpers/utils'
import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy'
import { buildDislikeActivity } from '../../lib/activitypub/send/send-dislike'
import { videoPlaylistElementAPGetValidator, videoPlaylistsGetValidator } from '../../middlewares/validators/videos/video-playlists'
import { VideoPlaylistModel } from '../../models/video/video-playlist'
import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element'
import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'

const activityPubClientRouter = express.Router()
@@ -213,7 +210,7 @@ async function videoController (req: express.Request, res: express.Response) {
// We need more attributes
const video = await VideoModel.loadForGetAPI(res.locals.video.id)

if (video.url.startsWith(CONFIG.WEBSERVER.URL) === false) return res.redirect(video.url)
if (video.url.startsWith(WEBSERVER.URL) === false) return res.redirect(video.url)

// We need captions to render AP object
video.VideoCaptions = await VideoCaptionModel.listVideoCaptions(video.id)
@@ -232,7 +229,7 @@ async function videoController (req: express.Request, res: express.Response) {
async function videoAnnounceController (req: express.Request, res: express.Response) {
const share = res.locals.videoShare

if (share.url.startsWith(CONFIG.WEBSERVER.URL) === false) return res.redirect(share.url)
if (share.url.startsWith(WEBSERVER.URL) === false) return res.redirect(share.url)

const { activity } = await buildAnnounceWithVideoAudience(share.Actor, share, res.locals.video, undefined)

@@ -306,7 +303,7 @@ async function videoChannelFollowingController (req: express.Request, res: expre
async function videoCommentController (req: express.Request, res: express.Response) {
const videoComment = res.locals.videoComment

if (videoComment.url.startsWith(CONFIG.WEBSERVER.URL) === false) return res.redirect(videoComment.url)
if (videoComment.url.startsWith(WEBSERVER.URL) === false) return res.redirect(videoComment.url)

const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined)
const isPublic = true // Comments are always public
@@ -324,7 +321,7 @@ async function videoCommentController (req: express.Request, res: express.Respon

async function videoRedundancyController (req: express.Request, res: express.Response) {
const videoRedundancy = res.locals.videoRedundancy
if (videoRedundancy.url.startsWith(CONFIG.WEBSERVER.URL) === false) return res.redirect(videoRedundancy.url)
if (videoRedundancy.url.startsWith(WEBSERVER.URL) === false) return res.redirect(videoRedundancy.url)

const serverActor = await getServerActor()

@@ -366,7 +363,7 @@ async function actorFollowing (req: express.Request, actor: ActorModel) {
return ActorFollowModel.listAcceptedFollowingUrlsForApi([ actor.id ], undefined, start, count)
}

return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.path, handler, req.query.page)
return activityPubCollectionPagination(WEBSERVER.URL + req.path, handler, req.query.page)
}

async function actorFollowers (req: express.Request, actor: ActorModel) {
@@ -374,7 +371,7 @@ async function actorFollowers (req: express.Request, actor: ActorModel) {
return ActorFollowModel.listAcceptedFollowerUrlsForAP([ actor.id ], undefined, start, count)
}

return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.path, handler, req.query.page)
return activityPubCollectionPagination(WEBSERVER.URL + req.path, handler, req.query.page)
}

async function actorPlaylists (req: express.Request, account: AccountModel) {
@@ -382,7 +379,7 @@ async function actorPlaylists (req: express.Request, account: AccountModel) {
return VideoPlaylistModel.listPublicUrlsOfForAP(account.id, start, count)
}

return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.path, handler, req.query.page)
return activityPubCollectionPagination(WEBSERVER.URL + req.path, handler, req.query.page)
}

function videoRates (req: express.Request, rateType: VideoRateType, video: VideoModel, url: string) {


+ 2
- 1
server/controllers/api/config.ts View File

@@ -4,7 +4,7 @@ import { ServerConfig, UserRight } from '../../../shared'
import { About } from '../../../shared/models/server/about.model'
import { CustomConfig } from '../../../shared/models/server/custom-config.model'
import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/signup'
import { CONFIG, CONSTRAINTS_FIELDS, reloadConfig } from '../../initializers'
import { CONSTRAINTS_FIELDS } from '../../initializers'
import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../middlewares'
import { customConfigUpdateValidator } from '../../middlewares/validators/config'
import { ClientHtml } from '../../lib/client-html'
@@ -14,6 +14,7 @@ import { getServerCommit } from '../../helpers/utils'
import { Emailer } from '../../lib/emailer'
import { isNumeric } from 'validator'
import { objectConverter } from '../../helpers/core-utils'
import { CONFIG, reloadConfig } from '../../initializers/config'

const packageJSON = require('../../../../package.json')
const configRouter = express.Router()


+ 1
- 1
server/controllers/api/oauth-clients.ts View File

@@ -1,7 +1,7 @@
import * as express from 'express'
import { OAuthClientLocal } from '../../../shared'
import { logger } from '../../helpers/logger'
import { CONFIG } from '../../initializers'
import { CONFIG } from '../../initializers/config'
import { asyncMiddleware } from '../../middlewares'
import { OAuthClientModel } from '../../models/oauth/oauth-client'



+ 2
- 1
server/controllers/api/server/logs.ts View File

@@ -3,10 +3,11 @@ import { UserRight } from '../../../../shared/models/users'
import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares'
import { mtimeSortFilesDesc } from '../../../../shared/utils/logs/logs'
import { readdir, readFile } from 'fs-extra'
import { CONFIG, MAX_LOGS_OUTPUT_CHARACTERS } from '../../../initializers'
import { MAX_LOGS_OUTPUT_CHARACTERS } from '../../../initializers'
import { join } from 'path'
import { getLogsValidator } from '../../../middlewares/validators/logs'
import { LogLevel } from '../../../../shared/models/server/log-level.type'
import { CONFIG } from '../../../initializers/config'

const logsRouter = express.Router()



+ 2
- 1
server/controllers/api/server/stats.ts View File

@@ -6,9 +6,10 @@ import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { VideoModel } from '../../../models/video/video'
import { VideoCommentModel } from '../../../models/video/video-comment'
import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy'
import { CONFIG, ROUTE_CACHE_LIFETIME } from '../../../initializers/constants'
import { ROUTE_CACHE_LIFETIME } from '../../../initializers/constants'
import { cacheRoute } from '../../../middlewares/cache'
import { VideoFileModel } from '../../../models/video/video-file'
import { CONFIG } from '../../../initializers/config'

const statsRouter = express.Router()



+ 4
- 3
server/controllers/api/users/index.ts View File

@@ -3,7 +3,7 @@ import * as RateLimit from 'express-rate-limit'
import { UserCreate, UserRight, UserRole, UserUpdate } from '../../../../shared'
import { logger } from '../../../helpers/logger'
import { getFormattedObjects } from '../../../helpers/utils'
import { CONFIG, RATES_LIMIT, sequelizeTypescript } from '../../../initializers'
import { RATES_LIMIT, sequelizeTypescript, WEBSERVER } from '../../../initializers'
import { Emailer } from '../../../lib/emailer'
import { Redis } from '../../../lib/redis'
import { createUserAccountAndChannelAndPlaylist } from '../../../lib/user'
@@ -43,6 +43,7 @@ import { myVideosHistoryRouter } from './my-history'
import { myNotificationsRouter } from './my-notifications'
import { Notifier } from '../../../lib/notifier'
import { mySubscriptionsRouter } from './my-subscriptions'
import { CONFIG } from '../../../initializers/config'

const auditLogger = auditLoggerFactory('users')

@@ -293,7 +294,7 @@ async function askResetUserPassword (req: express.Request, res: express.Response
const user = res.locals.user

const verificationString = await Redis.Instance.setResetPasswordVerificationString(user.id)
const url = CONFIG.WEBSERVER.URL + '/reset-password?userId=' + user.id + '&verificationString=' + verificationString
const url = WEBSERVER.URL + '/reset-password?userId=' + user.id + '&verificationString=' + verificationString
await Emailer.Instance.addPasswordResetEmailJob(user.email, url)

return res.status(204).end()
@@ -310,7 +311,7 @@ async function resetUserPassword (req: express.Request, res: express.Response) {

async function sendVerifyUserEmail (user: UserModel) {
const verificationString = await Redis.Instance.setVerifyEmailVerificationString(user.id)
const url = CONFIG.WEBSERVER.URL + '/verify-account/email?userId=' + user.id + '&verificationString=' + verificationString
const url = WEBSERVER.URL + '/verify-account/email?userId=' + user.id + '&verificationString=' + verificationString
await Emailer.Instance.addVerifyEmailJob(user.email, url)
return
}


+ 2
- 1
server/controllers/api/users/me.ts View File

@@ -2,7 +2,7 @@ import * as express from 'express'
import 'multer'
import { UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../../shared'
import { getFormattedObjects } from '../../../helpers/utils'
import { CONFIG, MIMETYPES, sequelizeTypescript } from '../../../initializers'
import { MIMETYPES, sequelizeTypescript } from '../../../initializers'
import { sendUpdateActor } from '../../../lib/activitypub/send'
import {
asyncMiddleware,
@@ -26,6 +26,7 @@ import { updateActorAvatarFile } from '../../../lib/avatar'
import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger'
import { VideoImportModel } from '../../../models/video/video-import'
import { AccountModel } from '../../../models/account/account'
import { CONFIG } from '../../../initializers/config'

const auditLogger = auditLoggerFactory('users-me')



+ 2
- 2
server/controllers/api/users/my-subscriptions.ts View File

@@ -1,7 +1,7 @@
import * as express from 'express'
import 'multer'
import { getFormattedObjects } from '../../../helpers/utils'
import { CONFIG, sequelizeTypescript } from '../../../initializers'
import { sequelizeTypescript, WEBSERVER } from '../../../initializers'
import {
asyncMiddleware,
asyncRetryTransactionMiddleware,
@@ -80,7 +80,7 @@ async function areSubscriptionsExist (req: express.Request, res: express.Respons

const handles = uris.map(u => {
let [ name, host ] = u.split('@')
if (host === CONFIG.WEBSERVER.HOST) host = null
if (host === WEBSERVER.HOST) host = null

return { name, host, uri: u }
})


+ 2
- 1
server/controllers/api/video-channel.ts View File

@@ -23,7 +23,7 @@ import { createVideoChannel } from '../../lib/video-channel'
import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
import { setAsyncActorKeys } from '../../lib/activitypub'
import { AccountModel } from '../../models/account/account'
import { CONFIG, MIMETYPES, sequelizeTypescript } from '../../initializers'
import { MIMETYPES, sequelizeTypescript } from '../../initializers'
import { logger } from '../../helpers/logger'
import { VideoModel } from '../../models/video/video'
import { updateAvatarValidator } from '../../middlewares/validators/avatar'
@@ -33,6 +33,7 @@ import { resetSequelizeInstance } from '../../helpers/database-utils'
import { JobQueue } from '../../lib/job-queue'
import { VideoPlaylistModel } from '../../models/video/video-playlist'
import { commonVideoPlaylistFiltersValidator } from '../../middlewares/validators/videos/video-playlists'
import { CONFIG } from '../../initializers/config'

const auditLogger = auditLoggerFactory('channels')
const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })


+ 2
- 1
server/controllers/api/video-playlist.ts View File

@@ -12,7 +12,7 @@ import {
} from '../../middlewares'
import { videoPlaylistsSortValidator } from '../../middlewares/validators'
import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
import { CONFIG, MIMETYPES, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers'
import { MIMETYPES, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers'
import { logger } from '../../helpers/logger'
import { resetSequelizeInstance } from '../../helpers/database-utils'
import { VideoPlaylistModel } from '../../models/video/video-playlist'
@@ -41,6 +41,7 @@ import { copy, pathExists } from 'fs-extra'
import { AccountModel } from '../../models/account/account'
import { VideoPlaylistReorder } from '../../../shared/models/videos/playlist/video-playlist-reorder.model'
import { JobQueue } from '../../lib/job-queue'
import { CONFIG } from '../../initializers/config'

const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR })



+ 2
- 1
server/controllers/api/videos/captions.ts View File

@@ -2,12 +2,13 @@ import * as express from 'express'
import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate } from '../../../middlewares'
import { addVideoCaptionValidator, deleteVideoCaptionValidator, listVideoCaptionsValidator } from '../../../middlewares/validators'
import { createReqFiles } from '../../../helpers/express-utils'
import { CONFIG, MIMETYPES, sequelizeTypescript } from '../../../initializers'
import { MIMETYPES, sequelizeTypescript } from '../../../initializers'
import { getFormattedObjects } from '../../../helpers/utils'
import { VideoCaptionModel } from '../../../models/video/video-caption'
import { logger } from '../../../helpers/logger'
import { federateVideoIfNeeded } from '../../../lib/activitypub'
import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils'
import { CONFIG } from '../../../initializers/config'

const reqVideoCaptionAdd = createReqFiles(
[ 'captionfile' ],


+ 3
- 2
server/controllers/api/videos/import.ts View File

@@ -3,7 +3,7 @@ import * as magnetUtil from 'magnet-uri'
import 'multer'
import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger'
import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares'
import { CONFIG, MIMETYPES, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE } from '../../../initializers'
import { MIMETYPES, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE } from '../../../initializers'
import { getYoutubeDLInfo, YoutubeDLInfo } from '../../../helpers/youtube-dl'
import { createReqFiles } from '../../../helpers/express-utils'
import { logger } from '../../../helpers/logger'
@@ -22,8 +22,9 @@ import { UserModel } from '../../../models/account/user'
import * as Bluebird from 'bluebird'
import * as parseTorrent from 'parse-torrent'
import { getSecureTorrentName } from '../../../helpers/utils'
import { readFile, move } from 'fs-extra'
import { move, readFile } from 'fs-extra'
import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist'
import { CONFIG } from '../../../initializers/config'

const auditLogger = auditLoggerFactory('video-imports')
const videoImportsRouter = express.Router()


+ 1
- 1
server/controllers/api/videos/index.ts View File

@@ -8,7 +8,6 @@ import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../
import { getFormattedObjects, getServerActor } from '../../../helpers/utils'
import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist'
import {
CONFIG,
MIMETYPES,
PREVIEWS_SIZE,
sequelizeTypescript,
@@ -61,6 +60,7 @@ import { move } from 'fs-extra'
import { watchingRouter } from './watching'
import { Notifier } from '../../../lib/notifier'
import { sendView } from '../../../lib/activitypub/send/send-view'
import { CONFIG } from '../../../initializers/config'

const auditLogger = auditLoggerFactory('videos')
const videosRouter = express.Router()


+ 8
- 8
server/controllers/bots.ts View File

@@ -1,6 +1,6 @@
import * as express from 'express'
import { asyncMiddleware } from '../middlewares'
import { CONFIG, ROUTE_CACHE_LIFETIME } from '../initializers'
import { ROUTE_CACHE_LIFETIME, WEBSERVER } from '../initializers'
import * as sitemapModule from 'sitemap'
import { logger } from '../helpers/logger'
import { VideoModel } from '../models/video/video'
@@ -35,7 +35,7 @@ async function getSitemap (req: express.Request, res: express.Response) {
urls = urls.concat(await getSitemapAccountUrls())

const sitemap = sitemapModule.createSitemap({
hostname: CONFIG.WEBSERVER.URL,
hostname: WEBSERVER.URL,
urls: urls
})

@@ -54,7 +54,7 @@ async function getSitemapVideoChannelUrls () {
const rows = await VideoChannelModel.listLocalsForSitemap('createdAt')

return rows.map(channel => ({
url: CONFIG.WEBSERVER.URL + '/video-channels/' + channel.Actor.preferredUsername
url: WEBSERVER.URL + '/video-channels/' + channel.Actor.preferredUsername
}))
}

@@ -62,7 +62,7 @@ async function getSitemapAccountUrls () {
const rows = await AccountModel.listLocalsForSitemap('createdAt')

return rows.map(channel => ({
url: CONFIG.WEBSERVER.URL + '/accounts/' + channel.Actor.preferredUsername
url: WEBSERVER.URL + '/accounts/' + channel.Actor.preferredUsername
}))
}

@@ -78,14 +78,14 @@ async function getSitemapLocalVideoUrls () {
})

return resultList.data.map(v => ({
url: CONFIG.WEBSERVER.URL + '/videos/watch/' + v.uuid,
url: WEBSERVER.URL + '/videos/watch/' + v.uuid,
video: [
{
title: v.name,
// Sitemap description should be < 2000 characters
description: truncate(v.description || v.name, { length: 2000, omission: '...' }),
player_loc: CONFIG.WEBSERVER.URL + '/videos/embed/' + v.uuid,
thumbnail_loc: CONFIG.WEBSERVER.URL + v.getThumbnailStaticPath()
player_loc: WEBSERVER.URL + '/videos/embed/' + v.uuid,
thumbnail_loc: WEBSERVER.URL + v.getThumbnailStaticPath()
}
]
}))
@@ -97,5 +97,5 @@ function getSitemapBasicUrls () {
'/videos/local'
]

return paths.map(p => ({ url: CONFIG.WEBSERVER.URL + p }))
return paths.map(p => ({ url: WEBSERVER.URL + p }))
}

+ 6
- 5
server/controllers/feeds.ts View File

@@ -1,5 +1,5 @@
import * as express from 'express'
import { CONFIG, FEEDS, ROUTE_CACHE_LIFETIME } from '../initializers/constants'
import { FEEDS, ROUTE_CACHE_LIFETIME, WEBSERVER } from '../initializers/constants'
import { THUMBNAILS_SIZE } from '../initializers'
import {
asyncMiddleware,
@@ -14,6 +14,7 @@ import * as Feed from 'pfeed'
import { cacheRoute } from '../middlewares/cache'
import { VideoCommentModel } from '../models/video/video-comment'
import { buildNSFWFilter } from '../helpers/express-utils'
import { CONFIG } from '../initializers/config'

const feedsRouter = express.Router()

@@ -54,7 +55,7 @@ async function generateVideoCommentsFeed (req: express.Request, res: express.Res

// Adding video items to the feed, one at a time
comments.forEach(comment => {
const link = CONFIG.WEBSERVER.URL + comment.getCommentStaticPath()
const link = WEBSERVER.URL + comment.getCommentStaticPath()

feed.addItem({
title: `${comment.Video.name} - ${comment.Account.getDisplayName()}`,
@@ -122,7 +123,7 @@ async function generateVideoFeed (req: express.Request, res: express.Response) {
feed.addItem({
title: video.name,
id: video.url,
link: CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid,
link: WEBSERVER.URL + '/videos/watch/' + video.uuid,
description: video.getTruncatedDescription(),
content: video.description,
author: [
@@ -137,7 +138,7 @@ async function generateVideoFeed (req: express.Request, res: express.Response) {
torrent: torrents,
thumbnail: [
{
url: CONFIG.WEBSERVER.URL + video.getThumbnailStaticPath(),
url: WEBSERVER.URL + video.getThumbnailStaticPath(),
height: THUMBNAILS_SIZE.height,
width: THUMBNAILS_SIZE.width
}
@@ -150,7 +151,7 @@ async function generateVideoFeed (req: express.Request, res: express.Response) {
}

function initFeed (name: string, description: string) {
const webserverUrl = CONFIG.WEBSERVER.URL
const webserverUrl = WEBSERVER.URL

return new Feed({
title: name,


+ 3
- 3
server/controllers/services.ts View File

@@ -1,8 +1,8 @@
import * as express from 'express'
import { CONFIG, EMBED_SIZE, PREVIEWS_SIZE } from '../initializers'
import { EMBED_SIZE, PREVIEWS_SIZE, WEBSERVER } from '../initializers'
import { asyncMiddleware, oembedValidator } from '../middlewares'
import { accountNameWithHostGetValidator } from '../middlewares/validators'
import { VideoModel } from '../models/video/video'
import { CONFIG } from '../initializers/config'

const servicesRouter = express.Router()

@@ -25,7 +25,7 @@ export {

function generateOEmbed (req: express.Request, res: express.Response) {
const video = res.locals.video
const webserverUrl = CONFIG.WEBSERVER.URL
const webserverUrl = WEBSERVER.URL
const maxHeight = parseInt(req.query.maxheight, 10)
const maxWidth = parseInt(req.query.maxwidth, 10)



+ 4
- 3
server/controllers/static.ts View File

@@ -1,12 +1,12 @@
import * as cors from 'cors'
import * as express from 'express'
import {
CONFIG,
HLS_STREAMING_PLAYLIST_DIRECTORY,
ROUTE_CACHE_LIFETIME,
STATIC_DOWNLOAD_PATHS,
STATIC_MAX_AGE,
STATIC_PATHS
STATIC_PATHS,
WEBSERVER
} from '../initializers'
import { VideosCaptionCache, VideosPreviewCache } from '../lib/files-cache'
import { cacheRoute } from '../middlewares/cache'
@@ -17,6 +17,7 @@ import { VideoCommentModel } from '../models/video/video-comment'
import { HttpNodeinfoDiasporaSoftwareNsSchema20 } from '../../shared/models/nodeinfo'
import { join } from 'path'
import { root } from '../helpers/core-utils'
import { CONFIG } from '../initializers/config'

const packageJSON = require('../../../package.json')
const staticRouter = express.Router()
@@ -121,7 +122,7 @@ staticRouter.use('/.well-known/nodeinfo',
links: [
{
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0',
href: CONFIG.WEBSERVER.URL + '/nodeinfo/2.0.json'
href: WEBSERVER.URL + '/nodeinfo/2.0.json'
}
]
})


+ 2
- 1
server/controllers/tracker.ts View File

@@ -4,10 +4,11 @@ import * as http from 'http'
import * as bitTorrentTracker from 'bittorrent-tracker'
import * as proxyAddr from 'proxy-addr'
import { Server as WebSocketServer } from 'ws'
import { CONFIG, TRACKER_RATE_LIMITS } from '../initializers/constants'
import { TRACKER_RATE_LIMITS } from '../initializers/constants'
import { VideoFileModel } from '../models/video/video-file'
import { parse } from 'url'
import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist'
import { CONFIG } from '../initializers/config'

const TrackerServer = bitTorrentTracker.Server



+ 1
- 1
server/helpers/audit-logger.ts View File

@@ -4,11 +4,11 @@ import { diff } from 'deep-object-diff'
import { chain } from 'lodash'
import * as flatten from 'flat'
import * as winston from 'winston'
import { CONFIG } from '../initializers'
import { jsonLoggerFormat, labelFormatter } from './logger'
import { User, VideoAbuse, VideoChannel, VideoDetails, VideoImport } from '../../shared'
import { VideoComment } from '../../shared/models/videos/video-comment.model'
import { CustomConfig } from '../../shared/models/server/custom-config.model'
import { CONFIG } from '../initializers/config'

function getAuditIdFromRes (res: express.Response) {
return res.locals.oauth.token.User.username


+ 1
- 1
server/helpers/captions-utils.ts View File

@@ -1,5 +1,5 @@
import { join } from 'path'
import { CONFIG } from '../initializers'
import { CONFIG } from '../initializers/config'
import { VideoCaptionModel } from '../models/video/video-caption'
import * as srt2vtt from 'srt-to-vtt'
import { createReadStream, createWriteStream, remove, move } from 'fs-extra'


+ 1
- 1
server/helpers/custom-validators/video-channels.ts View File

@@ -2,7 +2,7 @@ import * as express from 'express'
import 'express-validator'
import 'multer'
import * as validator from 'validator'
import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers'
import { CONSTRAINTS_FIELDS } from '../../initializers'
import { VideoChannelModel } from '../../models/video/video-channel'
import { exists } from './misc'



+ 2
- 2
server/helpers/custom-validators/webfinger.ts View File

@@ -1,4 +1,4 @@
import { CONFIG, REMOTE_SCHEME } from '../../initializers'
import { REMOTE_SCHEME, WEBSERVER } from '../../initializers'
import { sanitizeHost } from '../core-utils'
import { exists } from './misc'

@@ -11,7 +11,7 @@ function isWebfingerLocalResourceValid (value: string) {
if (actorParts.length !== 2) return false

const host = actorParts[1]
return sanitizeHost(host, REMOTE_SCHEME.HTTP) === CONFIG.WEBSERVER.HOST
return sanitizeHost(host, REMOTE_SCHEME.HTTP) === WEBSERVER.HOST
}

// ---------------------------------------------------------------------------


+ 3
- 2
server/helpers/express-utils.ts View File

@@ -1,10 +1,11 @@
import * as express from 'express'
import * as multer from 'multer'
import { CONFIG, REMOTE_SCHEME } from '../initializers'
import { REMOTE_SCHEME } from '../initializers'
import { logger } from './logger'
import { deleteFileAsync, generateRandomString } from './utils'
import { extname } from 'path'
import { isArray } from './custom-validators/misc'
import { CONFIG } from '../initializers/config'

function buildNSFWFilter (res?: express.Response, paramNSFW?: string) {
if (paramNSFW === 'true') return true
@@ -58,7 +59,7 @@ function getHostWithPort (host: string) {
return host
}

function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) {
function badRequest (req: express.Request, res: express.Response) {
return res.type('json').status(400).end()
}



+ 3
- 2
server/helpers/ffmpeg-utils.ts View File

@@ -1,11 +1,12 @@
import * as ffmpeg from 'fluent-ffmpeg'
import { dirname, join } from 'path'
import { getTargetBitrate, VideoResolution } from '../../shared/models/videos'
import { CONFIG, FFMPEG_NICE, VIDEO_TRANSCODING_FPS } from '../initializers/constants'
import { FFMPEG_NICE, VIDEO_TRANSCODING_FPS } from '../initializers/constants'
import { processImage } from './image-utils'
import { logger } from './logger'
import { checkFFmpegEncoders } from '../initializers/checker-before-init'
import { remove, readFile, writeFile } from 'fs-extra'
import { readFile, remove, writeFile } from 'fs-extra'
import { CONFIG } from '../initializers/config'

function computeResolutionsToTranscode (videoFileHeight: number) {
const resolutionsEnabled: number[] = []


+ 1
- 1
server/helpers/logger.ts View File

@@ -2,7 +2,7 @@
import { mkdirpSync } from 'fs-extra'
import * as path from 'path'
import * as winston from 'winston'
import { CONFIG } from '../initializers'
import { CONFIG } from '../initializers/config'
import { omit } from 'lodash'

const label = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT


+ 2
- 1
server/helpers/requests.ts View File

@@ -1,10 +1,11 @@
import * as Bluebird from 'bluebird'
import { createWriteStream, remove } from 'fs-extra'
import * as request from 'request'
import { ACTIVITY_PUB, CONFIG } from '../initializers'
import { ACTIVITY_PUB } from '../initializers'
import { processImage } from './image-utils'
import { join } from 'path'
import { logger } from './logger'
import { CONFIG } from '../initializers/config'

function doRequest <T> (
requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean },


+ 2
- 1
server/helpers/signup.ts View File

@@ -1,6 +1,7 @@
import { CONFIG } from '../initializers'
import { UserModel } from '../models/account/user'
import * as ipaddr from 'ipaddr.js'
import { CONFIG } from '../initializers/config'

const isCidr = require('is-cidr')

async function isSignupAllowed () {


+ 1
- 1
server/helpers/utils.ts View File

@@ -1,5 +1,4 @@
import { ResultList } from '../../shared'
import { CONFIG } from '../initializers'
import { ApplicationModel } from '../models/application/application'
import { execPromise, execPromise2, pseudoRandomBytesPromise, sha256 } from './core-utils'
import { logger } from './logger'
@@ -7,6 +6,7 @@ import { join } from 'path'
import { Instance as ParseTorrent } from 'parse-torrent'
import { remove } from 'fs-extra'
import * as memoizee from 'memoizee'
import { CONFIG } from '../initializers/config'

function deleteFileAsync (path: string) {
remove(path)


+ 2
- 2
server/helpers/webfinger.ts View File

@@ -3,7 +3,7 @@ import { WebFingerData } from '../../shared'
import { ActorModel } from '../models/activitypub/actor'
import { isTestInstance } from './core-utils'
import { isActivityPubUrlValid } from './custom-validators/activitypub/misc'
import { CONFIG } from '../initializers'
import { WEBSERVER } from '../initializers/constants'

const webfinger = new WebFinger({
webfist_fallback: false,
@@ -19,7 +19,7 @@ async function loadActorUrlOrGetFromWebfinger (uriArg: string) {
const [ name, host ] = uri.split('@')
let actor: ActorModel

if (host === CONFIG.WEBSERVER.HOST) {
if (host === WEBSERVER.HOST) {
actor = await ActorModel.loadLocalByName(name)
} else {
actor = await ActorModel.loadByNameAndHost(name, host)


+ 1
- 1
server/helpers/webtorrent.ts View File

@@ -2,7 +2,7 @@ import { logger } from './logger'
import { generateVideoImportTmpPath } from './utils'
import * as WebTorrent from 'webtorrent'
import { createWriteStream, ensureDir, remove } from 'fs-extra'
import { CONFIG } from '../initializers'
import { CONFIG } from '../initializers/config'
import { dirname, join } from 'path'

async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName?: string }, timeout: number) {


+ 3
- 2
server/initializers/checker-after-init.ts View File

@@ -4,19 +4,20 @@ import { UserModel } from '../models/account/user'
import { ApplicationModel } from '../models/application/application'
import { OAuthClientModel } from '../models/oauth/oauth-client'
import { parse } from 'url'
import { CONFIG } from './constants'
import { CONFIG } from './config'
import { logger } from '../helpers/logger'
import { getServerActor } from '../helpers/utils'
import { RecentlyAddedStrategy } from '../../shared/models/redundancy'
import { isArray } from '../helpers/custom-validators/misc'
import { uniq } from 'lodash'
import { Emailer } from '../lib/emailer'
import { WEBSERVER } from './constants'

async function checkActivityPubUrls () {
const actor = await getServerActor()

const parsed = parse(actor.url)
if (CONFIG.WEBSERVER.HOST !== parsed.host) {
if (WEBSERVER.HOST !== parsed.host) {
const NODE_ENV = config.util.getEnv('NODE_ENV')
const NODE_CONFIG_DIR = config.util.getEnv('NODE_CONFIG_DIR')



+ 255
- 0
server/initializers/config.ts View File

@@ -0,0 +1,255 @@
import { IConfig } from 'config'
import { dirname, join } from 'path'
import { VideosRedundancy } from '../../shared/models'
// Do not use barrels, remain constants as independent as possible
import { buildPath, parseBytes, parseDuration, root } from '../helpers/core-utils'
import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type'
import * as bytes from 'bytes'

// Use a variable to reload the configuration if we need
let config: IConfig = require('config')

const configChangedHandlers: Function[] = []

const CONFIG = {
CUSTOM_FILE: getLocalConfigFilePath(),
LISTEN: {
PORT: config.get<number>('listen.port'),
HOSTNAME: config.get<string>('listen.hostname')
},
DATABASE: {
DBNAME: 'peertube' + config.get<string>('database.suffix'),
HOSTNAME: config.get<string>('database.hostname'),
PORT: config.get<number>('database.port'),
USERNAME: config.get<string>('database.username'),
PASSWORD: config.get<string>('database.password'),
POOL: {
MAX: config.get<number>('database.pool.max')
}
},
REDIS: {
HOSTNAME: config.has('redis.hostname') ? config.get<string>('redis.hostname') : null,
PORT: config.has('redis.port') ? config.get<number>('redis.port') : null,
SOCKET: config.has('redis.socket') ? config.get<string>('redis.socket') : null,
AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null,
DB: config.has('redis.db') ? config.get<number>('redis.db') : null
},
SMTP: {
HOSTNAME: config.get<string>('smtp.hostname'),
PORT: config.get<number>('smtp.port'),
USERNAME: config.get<string>('smtp.username'),
PASSWORD: config.get<string>('smtp.password'),
TLS: config.get<boolean>('smtp.tls'),
DISABLE_STARTTLS: config.get<boolean>('smtp.disable_starttls'),
CA_FILE: config.get<string>('smtp.ca_file'),
FROM_ADDRESS: config.get<string>('smtp.from_address')
},
STORAGE: {
TMP_DIR: buildPath(config.get<string>('storage.tmp')),
AVATARS_DIR: buildPath(config.get<string>('storage.avatars')),
LOG_DIR: buildPath(config.get<string>('storage.logs')),
VIDEOS_DIR: buildPath(config.get<string>('storage.videos')),
STREAMING_PLAYLISTS_DIR: buildPath(config.get<string>('storage.streaming_playlists')),
REDUNDANCY_DIR: buildPath(config.get<string>('storage.redundancy')),
THUMBNAILS_DIR: buildPath(config.get<string>('storage.thumbnails')),
PREVIEWS_DIR: buildPath(config.get<string>('storage.previews')),
CAPTIONS_DIR: buildPath(config.get<string>('storage.captions')),
TORRENTS_DIR: buildPath(config.get<string>('storage.torrents')),
CACHE_DIR: buildPath(config.get<string>('storage.cache'))
},
WEBSERVER: {
SCHEME: config.get<boolean>('webserver.https') === true ? 'https' : 'http',
WS: config.get<boolean>('webserver.https') === true ? 'wss' : 'ws',
HOSTNAME: config.get<string>('webserver.hostname'),
PORT: config.get<number>('webserver.port')
},
TRUST_PROXY: config.get<string[]>('trust_proxy'),
LOG: {
LEVEL: config.get<string>('log.level')
},
SEARCH: {
REMOTE_URI: {
USERS: config.get<boolean>('search.remote_uri.users'),
ANONYMOUS: config.get<boolean>('search.remote_uri.anonymous')
}
},
TRENDING: {
VIDEOS: {
INTERVAL_DAYS: config.get<number>('trending.videos.interval_days')
}
},
REDUNDANCY: {
VIDEOS: {
CHECK_INTERVAL: parseDuration(config.get<string>('redundancy.videos.check_interval')),
STRATEGIES: buildVideosRedundancy(config.get<any[]>('redundancy.videos.strategies'))
}
},
CSP: {
ENABLED: config.get<boolean>('csp.enabled'),
REPORT_ONLY: config.get<boolean>('csp.report_only'),
REPORT_URI: config.get<boolean>('csp.report_uri')
},
TRACKER: {
ENABLED: config.get<boolean>('tracker.enabled'),
PRIVATE: config.get<boolean>('tracker.private'),
REJECT_TOO_MANY_ANNOUNCES: config.get<boolean>('tracker.reject_too_many_announces')
},
ADMIN: {
get EMAIL () { return config.get<string>('admin.email') }
},
CONTACT_FORM: {
get ENABLED () { return config.get<boolean>('contact_form.enabled') }
},
SIGNUP: {
get ENABLED () { return config.get<boolean>('signup.enabled') },
get LIMIT () { return config.get<number>('signup.limit') },
get REQUIRES_EMAIL_VERIFICATION () { return config.get<boolean>('signup.requires_email_verification') },
FILTERS: {
CIDR: {
get WHITELIST () { return config.get<string[]>('signup.filters.cidr.whitelist') },
get BLACKLIST () { return config.get<string[]>('signup.filters.cidr.blacklist') }
}
}
},
USER: {
get VIDEO_QUOTA () { return parseBytes(config.get<number>('user.video_quota')) },
get VIDEO_QUOTA_DAILY () { return parseBytes(config.get<number>('user.video_quota_daily')) }
},
TRANSCODING: {
get ENABLED () { return config.get<boolean>('transcoding.enabled') },
get ALLOW_ADDITIONAL_EXTENSIONS () { return config.get<boolean>('transcoding.allow_additional_extensions') },
get THREADS () { return config.get<number>('transcoding.threads') },
RESOLUTIONS: {
get '240p' () { return config.get<boolean>('transcoding.resolutions.240p') },
get '360p' () { return config.get<boolean>('transcoding.resolutions.360p') },
get '480p' () { return config.get<boolean>('transcoding.resolutions.480p') },
get '720p' () { return config.get<boolean>('transcoding.resolutions.720p') },
get '1080p' () { return config.get<boolean>('transcoding.resolutions.1080p') }
},
HLS: {
get ENABLED () { return config.get<boolean>('transcoding.hls.enabled') }
}
},
IMPORT: {
VIDEOS: {
HTTP: {
get ENABLED () { return config.get<boolean>('import.videos.http.enabled') }
},
TORRENT: {
get ENABLED () { return config.get<boolean>('import.videos.torrent.enabled') }
}
}
},
AUTO_BLACKLIST: {
VIDEOS: {
OF_USERS: {
get ENABLED () { return config.get<boolean>('auto_blacklist.videos.of_users.enabled') }
}
}
},
CACHE: {
PREVIEWS: {
get SIZE () { return config.get<number>('cache.previews.size') }
},
VIDEO_CAPTIONS: {
get SIZE () { return config.get<number>('cache.captions.size') }
}
},
INSTANCE: {
get NAME () { return config.get<string>('instance.name') },
get SHORT_DESCRIPTION () { return config.get<string>('instance.short_description') },
get DESCRIPTION () { return config.get<string>('instance.description') },
get TERMS () { return config.get<string>('instance.terms') },
get IS_NSFW () { return config.get<boolean>('instance.is_nsfw') },
get DEFAULT_CLIENT_ROUTE () { return config.get<string>('instance.default_client_route') },
get DEFAULT_NSFW_POLICY () { return config.get<NSFWPolicyType>('instance.default_nsfw_policy') },
CUSTOMIZATIONS: {
get JAVASCRIPT () { return config.get<string>('instance.customizations.javascript') },
get CSS () { return config.get<string>('instance.customizations.css') }
},
get ROBOTS () { return config.get<string>('instance.robots') },
get SECURITYTXT () { return config.get<string>('instance.securitytxt') },
get SECURITYTXT_CONTACT () { return config.get<string>('admin.email') }
},
SERVICES: {
TWITTER: {
get USERNAME () { return config.get<string>('services.twitter.username') },
get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') }
}
},
FOLLOWERS: {
INSTANCE: {
get ENABLED () { return config.get<boolean>('followers.instance.enabled') },
get MANUAL_APPROVAL () { return config.get<boolean>('followers.instance.manual_approval') }
}
}
}

function registerConfigChangedHandler (fun: Function) {
configChangedHandlers.push(fun)
}

// ---------------------------------------------------------------------------

export {
CONFIG,
registerConfigChangedHandler
}

// ---------------------------------------------------------------------------

function getLocalConfigFilePath () {
const configSources = config.util.getConfigSources()
if (configSources.length === 0) throw new Error('Invalid config source.')

let filename = 'local'
if (process.env.NODE_ENV) filename += `-${process.env.NODE_ENV}`
if (process.env.NODE_APP_INSTANCE) filename += `-${process.env.NODE_APP_INSTANCE}`

return join(dirname(configSources[ 0 ].name), filename + '.json')
}

function buildVideosRedundancy (objs: any[]): VideosRedundancy[] {
if (!objs) return []

if (!Array.isArray(objs)) return objs

return objs.map(obj => {
return Object.assign({}, obj, {
minLifetime: parseDuration(obj.min_lifetime),
size: bytes.parse(obj.size),
minViews: obj.min_views
})
})
}

export function reloadConfig () {

function directory () {
if (process.env.NODE_CONFIG_DIR) {
return process.env.NODE_CONFIG_DIR
}

return join(root(), 'config')
}

function purge () {
for (const fileName in require.cache) {
if (-1 === fileName.indexOf(directory())) {
continue
}

delete require.cache[fileName]
}

delete require.cache[require.resolve('config')]
}

purge()

config = require('config')

for (const configChangedHandler of configChangedHandlers) {
configChangedHandler()
}
}

+ 51
- 270
server/initializers/constants.ts View File

@@ -1,20 +1,16 @@
import { IConfig } from 'config'
import { dirname, join } from 'path'
import { JobType, VideoRateType, VideoState, VideosRedundancy } from '../../shared/models'
import { join } from 'path'
import { JobType, VideoRateType, VideoState } from '../../shared/models'
import { ActivityPubActorType } from '../../shared/models/activitypub'
import { FollowState } from '../../shared/models/actors'
import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } from '../../shared/models/videos'
// Do not use barrels, remain constants as independent as possible
import { buildPath, isTestInstance, parseDuration, parseBytes, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils'
import { isTestInstance, sanitizeHost, sanitizeUrl } from '../helpers/core-utils'
import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type'
import { invert } from 'lodash'
import { CronRepeatOptions, EveryRepeatOptions } from 'bull'
import * as bytes from 'bytes'
import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model'
import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model'

// Use a variable to reload the configuration if we need
let config: IConfig = require('config')
import { CONFIG, registerConfigChangedHandler } from './config'

// ---------------------------------------------------------------------------

@@ -32,6 +28,15 @@ const PAGINATION = {
}
}

const WEBSERVER = {
URL: '',
HOST: '',
SCHEME: '',
WS: '',
HOSTNAME: '',
PORT: 0
}

// Sortable columns per schema
const SORTABLE_COLUMNS = {
USERS: [ 'id', 'username', 'createdAt' ],
@@ -102,7 +107,7 @@ const REMOTE_SCHEME = {
}

// TODO: remove 'video-file'
const JOB_ATTEMPTS: { [ id in (JobType | 'video-file') ]: number } = {
const JOB_ATTEMPTS: { [id in (JobType | 'video-file')]: number } = {
'activitypub-http-broadcast': 5,
'activitypub-http-unicast': 5,
'activitypub-http-fetcher': 5,
@@ -115,7 +120,7 @@ const JOB_ATTEMPTS: { [ id in (JobType | 'video-file') ]: number } = {
'videos-views': 1,
'activitypub-refresher': 1
}
const JOB_CONCURRENCY: { [ id in (JobType | 'video-file') ]: number } = {
const JOB_CONCURRENCY: { [id in (JobType | 'video-file')]: number } = {
'activitypub-http-broadcast': 1,
'activitypub-http-unicast': 5,
'activitypub-http-fetcher': 1,
@@ -128,7 +133,7 @@ const JOB_CONCURRENCY: { [ id in (JobType | 'video-file') ]: number } = {
'videos-views': 1,
'activitypub-refresher': 1
}
const JOB_TTL: { [ id in (JobType | 'video-file') ]: number } = {
const JOB_TTL: { [id in (JobType | 'video-file')]: number } = {
'activitypub-http-broadcast': 60000 * 10, // 10 minutes
'activitypub-http-unicast': 60000 * 10, // 10 minutes
'activitypub-http-fetcher': 60000 * 10, // 10 minutes
@@ -163,184 +168,6 @@ let SCHEDULER_INTERVALS_MS = {

// ---------------------------------------------------------------------------

const CONFIG = {
CUSTOM_FILE: getLocalConfigFilePath(),
LISTEN: {
PORT: config.get<number>('listen.port'),
HOSTNAME: config.get<string>('listen.hostname')
},
DATABASE: {
DBNAME: 'peertube' + config.get<string>('database.suffix'),
HOSTNAME: config.get<string>('database.hostname'),
PORT: config.get<number>('database.port'),
USERNAME: config.get<string>('database.username'),
PASSWORD: config.get<string>('database.password'),
POOL: {
MAX: config.get<number>('database.pool.max')
}
},
REDIS: {
HOSTNAME: config.has('redis.hostname') ? config.get<string>('redis.hostname') : null,
PORT: config.has('redis.port') ? config.get<number>('redis.port') : null,
SOCKET: config.has('redis.socket') ? config.get<string>('redis.socket') : null,
AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null,
DB: config.has('redis.db') ? config.get<number>('redis.db') : null
},
SMTP: {
HOSTNAME: config.get<string>('smtp.hostname'),
PORT: config.get<number>('smtp.port'),
USERNAME: config.get<string>('smtp.username'),
PASSWORD: config.get<string>('smtp.password'),
TLS: config.get<boolean>('smtp.tls'),
DISABLE_STARTTLS: config.get<boolean>('smtp.disable_starttls'),
CA_FILE: config.get<string>('smtp.ca_file'),
FROM_ADDRESS: config.get<string>('smtp.from_address')
},
STORAGE: {
TMP_DIR: buildPath(config.get<string>('storage.tmp')),
AVATARS_DIR: buildPath(config.get<string>('storage.avatars')),
LOG_DIR: buildPath(config.get<string>('storage.logs')),
VIDEOS_DIR: buildPath(config.get<string>('storage.videos')),
STREAMING_PLAYLISTS_DIR: buildPath(config.get<string>('storage.streaming_playlists')),
REDUNDANCY_DIR: buildPath(config.get<string>('storage.redundancy')),
THUMBNAILS_DIR: buildPath(config.get<string>('storage.thumbnails')),
PREVIEWS_DIR: buildPath(config.get<string>('storage.previews')),
CAPTIONS_DIR: buildPath(config.get<string>('storage.captions')),
TORRENTS_DIR: buildPath(config.get<string>('storage.torrents')),
CACHE_DIR: buildPath(config.get<string>('storage.cache'))
},
WEBSERVER: {
SCHEME: config.get<boolean>('webserver.https') === true ? 'https' : 'http',
WS: config.get<boolean>('webserver.https') === true ? 'wss' : 'ws',
HOSTNAME: config.get<string>('webserver.hostname'),
PORT: config.get<number>('webserver.port'),
URL: '',
HOST: ''
},
TRUST_PROXY: config.get<string[]>('trust_proxy'),
LOG: {
LEVEL: config.get<string>('log.level')
},
SEARCH: {
REMOTE_URI: {
USERS: config.get<boolean>('search.remote_uri.users'),
ANONYMOUS: config.get<boolean>('search.remote_uri.anonymous')
}
},
TRENDING: {
VIDEOS: {
INTERVAL_DAYS: config.get<number>('trending.videos.interval_days')
}
},
REDUNDANCY: {
VIDEOS: {
CHECK_INTERVAL: parseDuration(config.get<string>('redundancy.videos.check_interval')),
STRATEGIES: buildVideosRedundancy(config.get<any[]>('redundancy.videos.strategies'))
}
},
CSP: {
ENABLED: config.get<boolean>('csp.enabled'),
REPORT_ONLY: config.get<boolean>('csp.report_only'),
REPORT_URI: config.get<boolean>('csp.report_uri')
},
TRACKER: {
ENABLED: config.get<boolean>('tracker.enabled'),
PRIVATE: config.get<boolean>('tracker.private'),
REJECT_TOO_MANY_ANNOUNCES: config.get<boolean>('tracker.reject_too_many_announces')
},
ADMIN: {
get EMAIL () { return config.get<string>('admin.email') }
},
CONTACT_FORM: {
get ENABLED () { return config.get<boolean>('contact_form.enabled') }
},
SIGNUP: {
get ENABLED () { return config.get<boolean>('signup.enabled') },
get LIMIT () { return config.get<number>('signup.limit') },
get REQUIRES_EMAIL_VERIFICATION () { return config.get<boolean>('signup.requires_email_verification') },
FILTERS: {
CIDR: {
get WHITELIST () { return config.get<string[]>('signup.filters.cidr.whitelist') },
get BLACKLIST () { return config.get<string[]>('signup.filters.cidr.blacklist') }
}
}
},
USER: {
get VIDEO_QUOTA () { return parseBytes(config.get<number>('user.video_quota')) },
get VIDEO_QUOTA_DAILY () { return parseBytes(config.get<number>('user.video_quota_daily')) }
},
TRANSCODING: {
get ENABLED () { return config.get<boolean>('transcoding.enabled') },
get ALLOW_ADDITIONAL_EXTENSIONS () { return config.get<boolean>('transcoding.allow_additional_extensions') },
get THREADS () { return config.get<number>('transcoding.threads') },
RESOLUTIONS: {
get '240p' () { return config.get<boolean>('transcoding.resolutions.240p') },
get '360p' () { return config.get<boolean>('transcoding.resolutions.360p') },
get '480p' () { return config.get<boolean>('transcoding.resolutions.480p') },
get '720p' () { return config.get<boolean>('transcoding.resolutions.720p') },
get '1080p' () { return config.get<boolean>('transcoding.resolutions.1080p') }
},
HLS: {
get ENABLED () { return config.get<boolean>('transcoding.hls.enabled') }
}
},
IMPORT: {
VIDEOS: {
HTTP: {
get ENABLED () { return config.get<boolean>('import.videos.http.enabled') }
},
TORRENT: {
get ENABLED () { return config.get<boolean>('import.videos.torrent.enabled') }
}
}
},
AUTO_BLACKLIST: {
VIDEOS: {
OF_USERS: {
get ENABLED () { return config.get<boolean>('auto_blacklist.videos.of_users.enabled') }
}
}
},
CACHE: {
PREVIEWS: {
get SIZE () { return config.get<number>('cache.previews.size') }
},
VIDEO_CAPTIONS: {
get SIZE () { return config.get<number>('cache.captions.size') }
}
},
INSTANCE: {
get NAME () { return config.get<string>('instance.name') },
get SHORT_DESCRIPTION () { return config.get<string>('instance.short_description') },
get DESCRIPTION () { return config.get<string>('instance.description') },
get TERMS () { return config.get<string>('instance.terms') },
get IS_NSFW () { return config.get<boolean>('instance.is_nsfw') },
get DEFAULT_CLIENT_ROUTE () { return config.get<string>('instance.default_client_route') },
get DEFAULT_NSFW_POLICY () { return config.get<NSFWPolicyType>('instance.default_nsfw_policy') },
CUSTOMIZATIONS: {
get JAVASCRIPT () { return config.get<string>('instance.customizations.javascript') },
get CSS () { return config.get<string>('instance.customizations.css') }
},
get ROBOTS () { return config.get<string>('instance.robots') },
get SECURITYTXT () { return config.get<string>('instance.securitytxt') },
get SECURITYTXT_CONTACT () { return config.get<string>('admin.email') }
},
SERVICES: {
TWITTER: {
get USERNAME () { return config.get<string>('services.twitter.username') },
get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') }
}
},
FOLLOWERS: {
INSTANCE: {
get ENABLED () { return config.get<boolean>('followers.instance.enabled') },
get MANUAL_APPROVAL () { return config.get<boolean>('followers.instance.manual_approval') }
}
}
}

// ---------------------------------------------------------------------------

let CONSTRAINTS_FIELDS = {
USERS: {
NAME: { min: 1, max: 120 }, // Length
@@ -517,38 +344,38 @@ const VIDEO_LICENCES = {
const VIDEO_LANGUAGES = buildLanguages()

const VIDEO_PRIVACIES = {
[VideoPrivacy.PUBLIC]: 'Public',
[VideoPrivacy.UNLISTED]: 'Unlisted',
[VideoPrivacy.PRIVATE]: 'Private'
[ VideoPrivacy.PUBLIC ]: 'Public',
[ VideoPrivacy.UNLISTED ]: 'Unlisted',
[ VideoPrivacy.PRIVATE ]: 'Private'
}

const VIDEO_STATES = {
[VideoState.PUBLISHED]: 'Published',
[VideoState.TO_TRANSCODE]: 'To transcode',
[VideoState.TO_IMPORT]: 'To import'
[ VideoState.PUBLISHED ]: 'Published',
[ VideoState.TO_TRANSCODE ]: 'To transcode',
[ VideoState.TO_IMPORT ]: 'To import'
}

const VIDEO_IMPORT_STATES = {
[VideoImportState.FAILED]: 'Failed',
[VideoImportState.PENDING]: 'Pending',
[VideoImportState.SUCCESS]: 'Success'
[ VideoImportState.FAILED ]: 'Failed',
[ VideoImportState.PENDING ]: 'Pending',
[ VideoImportState.SUCCESS ]: 'Success'
}

const VIDEO_ABUSE_STATES = {
[VideoAbuseState.PENDING]: 'Pending',
[VideoAbuseState.REJECTED]: 'Rejected',
[VideoAbuseState.ACCEPTED]: 'Accepted'
[ VideoAbuseState.PENDING ]: 'Pending',
[ VideoAbuseState.REJECTED ]: 'Rejected',
[ VideoAbuseState.ACCEPTED ]: 'Accepted'
}

const VIDEO_PLAYLIST_PRIVACIES = {
[VideoPlaylistPrivacy.PUBLIC]: 'Public',
[VideoPlaylistPrivacy.UNLISTED]: 'Unlisted',
[VideoPlaylistPrivacy.PRIVATE]: 'Private'
[ VideoPlaylistPrivacy.PUBLIC ]: 'Public',
[ VideoPlaylistPrivacy.UNLISTED ]: 'Unlisted',
[ VideoPlaylistPrivacy.PRIVATE ]: 'Private'
}

const VIDEO_PLAYLIST_TYPES = {
[VideoPlaylistType.REGULAR]: 'Regular',
[VideoPlaylistType.WATCH_LATER]: 'Watch later'
[ VideoPlaylistType.REGULAR ]: 'Regular',
[ VideoPlaylistType.WATCH_LATER ]: 'Watch later'
}

const MIMETYPES = {
@@ -634,7 +461,7 @@ const USER_PASSWORD_RESET_LIFETIME = 60000 * 5 // 5 minutes

const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes

const NSFW_POLICY_TYPES: { [ id: string]: NSFWPolicyType } = {
const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = {
DO_NOT_LIST: 'do_not_list',
BLUR: 'blur',
DISPLAY: 'display'
@@ -765,14 +592,14 @@ if (isTestInstance() === true) {
SCHEDULER_INTERVALS_MS.actorFollowScores = 1000
SCHEDULER_INTERVALS_MS.removeOldJobs = 10000
SCHEDULER_INTERVALS_MS.updateVideos = 5000
REPEAT_JOBS['videos-views'] = { every: 5000 }
REPEAT_JOBS[ 'videos-views' ] = { every: 5000 }

REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1

VIDEO_VIEW_LIFETIME = 1000 // 1 second
CONTACT_FORM_LIFETIME = 1000 // 1 second

JOB_ATTEMPTS['email'] = 1
JOB_ATTEMPTS[ 'email' ] = 1

FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000
MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1
@@ -783,9 +610,15 @@ if (isTestInstance() === true) {

updateWebserverUrls()

registerConfigChangedHandler(() => {
updateWebserverUrls()
updateWebserverConfig()
})

// ---------------------------------------------------------------------------

export {
WEBSERVER,
API_VERSION,
HLS_REDUNDANCY_DIRECTORY,
P2P_MEDIA_LOADER_PEER_VERSION,
@@ -794,7 +627,6 @@ export {
BCRYPT_SALT_SIZE,
TRACKER_RATE_LIMITS,
FILES_CACHE,
CONFIG,
CONSTRAINTS_FIELDS,
EMBED_SIZE,
REDUNDANCY,
@@ -857,17 +689,6 @@ export {

// ---------------------------------------------------------------------------

function getLocalConfigFilePath () {
const configSources = config.util.getConfigSources()
if (configSources.length === 0) throw new Error('Invalid config source.')

let filename = 'local'
if (process.env.NODE_ENV) filename += `-${process.env.NODE_ENV}`
if (process.env.NODE_APP_INSTANCE) filename += `-${process.env.NODE_APP_INSTANCE}`

return join(dirname(configSources[ 0 ].name), filename + '.json')
}

function buildVideoMimetypeExt () {
const data = {
'video/webm': '.webm',
@@ -890,8 +711,12 @@ function buildVideoMimetypeExt () {
}

function updateWebserverUrls () {
CONFIG.WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT)
CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP)
WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT)
WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP)
WEBSERVER.SCHEME = CONFIG.WEBSERVER.SCHEME
WEBSERVER.WS = CONFIG.WEBSERVER.WS
WEBSERVER.HOSTNAME = CONFIG.WEBSERVER.HOSTNAME
WEBSERVER.PORT = CONFIG.WEBSERVER.PORT
}

function updateWebserverConfig () {
@@ -907,20 +732,6 @@ function buildVideosExtname () {
: [ '.mp4', '.ogv', '.webm' ]
}

function buildVideosRedundancy (objs: any[]): VideosRedundancy[] {
if (!objs) return []

if (!Array.isArray(objs)) return objs

return objs.map(obj => {
return Object.assign({}, obj, {
minLifetime: parseDuration(obj.min_lifetime),
size: bytes.parse(obj.size),
minViews: obj.min_views
})
})
}

function buildLanguages () {
const iso639 = require('iso-639-3')

@@ -953,42 +764,12 @@ function buildLanguages () {
iso639
.filter(l => {
return (l.iso6391 !== null && l.type === 'living') ||
additionalLanguages[l.iso6393] === true
additionalLanguages[ l.iso6393 ] === true
})
.forEach(l => languages[l.iso6391 || l.iso6393] = l.name)
.forEach(l => languages[ l.iso6391 || l.iso6393 ] = l.name)

// Override Occitan label
languages['oc'] = 'Occitan'
languages[ 'oc' ] = 'Occitan'

return languages
}

export function reloadConfig () {

function directory () {
if (process.env.NODE_CONFIG_DIR) {
return process.env.NODE_CONFIG_DIR
}

return join(root(), 'config')
}

function purge () {
for (const fileName in require.cache) {
if (-1 === fileName.indexOf(directory())) {
continue
}

delete require.cache[fileName]
}

delete require.cache[require.resolve('config')]
}

purge()

config = require('config')

updateWebserverConfig()
updateWebserverUrls()
}

+ 1
- 1
server/initializers/database.ts View File

@@ -21,7 +21,7 @@ import { VideoCommentModel } from '../models/video/video-comment'
import { VideoFileModel } from '../models/video/video-file'
import { VideoShareModel } from '../models/video/video-share'
import { VideoTagModel } from '../models/video/video-tag'
import { CONFIG } from './constants'
import { CONFIG } from './config'
import { ScheduleVideoUpdateModel } from '../models/video/schedule-video-update'
import { VideoCaptionModel } from '../models/video/video-caption'
import { VideoImportModel } from '../models/video/video-import'


+ 3
- 2
server/initializers/installer.ts View File

@@ -6,9 +6,10 @@ import { UserModel } from '../models/account/user'
import { ApplicationModel } from '../models/application/application'
import { OAuthClientModel } from '../models/oauth/oauth-client'
import { applicationExist, clientsExist, usersExist } from './checker-after-init'
import { FILES_CACHE, CONFIG, HLS_STREAMING_PLAYLIST_DIRECTORY, LAST_MIGRATION_VERSION } from './constants'
import { FILES_CACHE, HLS_STREAMING_PLAYLIST_DIRECTORY, LAST_MIGRATION_VERSION } from './constants'
import { sequelizeTypescript } from './database'
import { remove, ensureDir } from 'fs-extra'
import { ensureDir, remove } from 'fs-extra'
import { CONFIG } from './config'

async function installApplication () {
try {


+ 1
- 1
server/initializers/migrations/0075-video-resolutions.ts View File

@@ -1,6 +1,6 @@
import * as Sequelize from 'sequelize'
import { join } from 'path'
import { CONFIG } from '../../initializers/constants'
import { CONFIG } from '../../initializers/config'
import { getVideoFileResolution } from '../../helpers/ffmpeg-utils'
import { readdir, rename } from 'fs-extra'



+ 3
- 3
server/initializers/migrations/0140-actor-url.ts View File

@@ -1,13 +1,13 @@
import * as Sequelize from 'sequelize'
import { CONFIG } from '../constants'
import { WEBSERVER } from '../constants'

async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize
}): Promise<void> {
const toReplace = CONFIG.WEBSERVER.HOSTNAME + ':443'
const by = CONFIG.WEBSERVER.HOST
const toReplace = WEBSERVER.HOSTNAME + ':443'
const by = WEBSERVER.HOST
const replacer = column => `replace("${column}", '${toReplace}', '${by}')`

{


+ 0
- 4
server/initializers/migrations/0235-delete-some-video-indexes.ts View File

@@ -1,8 +1,4 @@
import * as Sequelize from 'sequelize'
import { createClient } from 'redis'
import { CONFIG } from '../constants'
import { JobQueue } from '../../lib/job-queue'
import { initDatabaseModels } from '../database'

async function up (utils: {
transaction: Sequelize.Transaction


+ 0
- 4
server/initializers/migrations/0240-drop-old-indexes.ts View File

@@ -1,8 +1,4 @@
import * as Sequelize from 'sequelize'
import { createClient } from 'redis'
import { CONFIG } from '../constants'
import { JobQueue } from '../../lib/job-queue'
import { initDatabaseModels } from '../database'

async function up (utils: {
transaction: Sequelize.Transaction


+ 2
- 2
server/initializers/migrations/0345-video-playlists.ts View File

@@ -1,7 +1,7 @@
import * as Sequelize from 'sequelize'
import { CONFIG } from '../constants'
import { VideoPlaylistPrivacy, VideoPlaylistType } from '../../../shared/models/videos'
import * as uuidv4 from 'uuid/v4'
import { WEBSERVER } from '../constants'

async function up (utils: {
transaction: Sequelize.Transaction,
@@ -57,7 +57,7 @@ CREATE TABLE IF NOT EXISTS "videoPlaylistElement"
for (const username of usernames) {
const uuid = uuidv4()

const baseUrl = CONFIG.WEBSERVER.URL + '/video-playlists/' + uuid
const baseUrl = WEBSERVER.URL + '/video-playlists/' + uuid
const query = `
INSERT INTO "videoPlaylist" ("url", "uuid", "name", "privacy", "type", "ownerAccountId", "createdAt", "updatedAt")
SELECT '${baseUrl}' AS "url",


+ 3
- 2
server/lib/activitypub/actor.ts View File

@@ -12,7 +12,7 @@ import { logger } from '../../helpers/logger'
import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
import { doRequest, downloadImage } from '../../helpers/requests'
import { getUrlFromWebfinger } from '../../helpers/webfinger'
import { AVATARS_SIZE, CONFIG, MIMETYPES, sequelizeTypescript } from '../../initializers'
import { AVATARS_SIZE, MIMETYPES, sequelizeTypescript, WEBSERVER } from '../../initializers'
import { AccountModel } from '../../models/account/account'
import { ActorModel } from '../../models/activitypub/actor'
import { AvatarModel } from '../../models/avatar/avatar'
@@ -21,6 +21,7 @@ import { VideoChannelModel } from '../../models/video/video-channel'
import { JobQueue } from '../job-queue'
import { getServerActor } from '../../helpers/utils'
import { ActorFetchByUrlType, fetchActorByUrl } from '../../helpers/actor'
import { CONFIG } from '../../initializers/config'

// Set account keys, this could be long so process after the account creation and do not block the client
function setAsyncActorKeys (actor: ActorModel) {
@@ -116,7 +117,7 @@ function buildActorInstance (type: ActivityPubActorType, url: string, preferredU
followingCount: 0,
inboxUrl: url + '/inbox',
outboxUrl: url + '/outbox',
sharedInboxUrl: CONFIG.WEBSERVER.URL + '/inbox',
sharedInboxUrl: WEBSERVER.URL + '/inbox',
followersUrl: url + '/followers',
followingUrl: url + '/following'
})


+ 2
- 1
server/lib/activitypub/playlist.ts View File

@@ -1,6 +1,6 @@
import { PlaylistObject } from '../../../shared/models/activitypub/objects/playlist-object'
import { crawlCollectionPage } from './crawl'
import { ACTIVITY_PUB, CONFIG, CRAWL_REQUEST_CONCURRENCY, sequelizeTypescript, THUMBNAILS_SIZE } from '../../initializers'
import { ACTIVITY_PUB, CRAWL_REQUEST_CONCURRENCY, sequelizeTypescript, THUMBNAILS_SIZE } from '../../initializers'
import { AccountModel } from '../../models/account/account'
import { isArray } from '../../helpers/custom-validators/misc'
import { getOrCreateActorAndServerAndModel } from './actor'
@@ -17,6 +17,7 @@ import { VideoModel } from '../../models/video/video'
import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
import { CONFIG } from '../../initializers/config'

function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount: AccountModel, to: string[]) {
const privacy = to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1 ? VideoPlaylistPrivacy.PUBLIC : VideoPlaylistPrivacy.UNLISTED


+ 2
- 1
server/lib/activitypub/process/process-follow.ts View File

@@ -1,13 +1,14 @@
import { ActivityFollow } from '../../../../shared/models/activitypub'
import { retryTransactionWrapper } from '../../../helpers/database-utils'
import { logger } from '../../../helpers/logger'
import { sequelizeTypescript, CONFIG } from '../../../initializers'
import { sequelizeTypescript } from '../../../initializers'
import { ActorModel } from '../../../models/activitypub/actor'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { sendAccept, sendReject } from '../send'
import { Notifier } from '../../notifier'
import { getAPId } from '../../../helpers/activitypub'
import { getServerActor } from '../../../helpers/utils'
import { CONFIG } from '../../../initializers/config'

async function processFollowActivity (activity: ActivityFollow, byActor: ActorModel) {
const activityObject = getAPId(activity.object)


+ 10
- 10
server/lib/activitypub/url.ts View File

@@ -1,4 +1,4 @@
import { CONFIG } from '../../initializers'
import { WEBSERVER } from '../../initializers'
import { ActorModel } from '../../models/activitypub/actor'
import { ActorFollowModel } from '../../models/activitypub/actor-follow'
import { VideoModel } from '../../models/video/video'
@@ -9,41 +9,41 @@ import { VideoStreamingPlaylistModel } from '../../models/video/video-streaming-
import { VideoPlaylistModel } from '../../models/video/video-playlist'

function getVideoActivityPubUrl (video: VideoModel) {
return CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid
return WEBSERVER.URL + '/videos/watch/' + video.uuid
}

function getVideoPlaylistActivityPubUrl (videoPlaylist: VideoPlaylistModel) {
return CONFIG.WEBSERVER.URL + '/video-playlists/' + videoPlaylist.uuid
return WEBSERVER.URL + '/video-playlists/' + videoPlaylist.uuid
}

function getVideoPlaylistElementActivityPubUrl (videoPlaylist: VideoPlaylistModel, video: VideoModel) {
return CONFIG.WEBSERVER.URL + '/video-playlists/' + videoPlaylist.uuid + '/' + video.uuid
return WEBSERVER.URL + '/video-playlists/' + videoPlaylist.uuid + '/' + video.uuid
}

function getVideoCacheFileActivityPubUrl (videoFile: VideoFileModel) {
const suffixFPS = videoFile.fps && videoFile.fps !== -1 ? '-' + videoFile.fps : ''

return `${CONFIG.WEBSERVER.URL}/redundancy/videos/${videoFile.Video.uuid}/${videoFile.resolution}${suffixFPS}`
return `${WEBSERVER.URL}/redundancy/videos/${videoFile.Video.uuid}/${videoFile.resolution}${suffixFPS}`
}

function getVideoCacheStreamingPlaylistActivityPubUrl (video: VideoModel, playlist: VideoStreamingPlaylistModel) {
return `${CONFIG.WEBSERVER.URL}/redundancy/streaming-playlists/${playlist.getStringType()}/${video.uuid}`
return `${WEBSERVER.URL}/redundancy/streaming-playlists/${playlist.getStringType()}/${video.uuid}`
}

function getVideoCommentActivityPubUrl (video: VideoModel, videoComment: VideoCommentModel) {
return CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid + '/comments/' + videoComment.id
return WEBSERVER.URL + '/videos/watch/' + video.uuid + '/comments/' + videoComment.id
}

function getVideoChannelActivityPubUrl (videoChannelName: string) {
return CONFIG.WEBSERVER.URL + '/video-channels/' + videoChannelName
return WEBSERVER.URL + '/video-channels/' + videoChannelName
}

function getAccountActivityPubUrl (accountName: string) {
return CONFIG.WEBSERVER.URL + '/accounts/' + accountName
return WEBSERVER.URL + '/accounts/' + accountName
}

function getVideoAbuseActivityPubUrl (videoAbuse: VideoAbuseModel) {
return CONFIG.WEBSERVER.URL + '/admin/video-abuses/' + videoAbuse.id
return WEBSERVER.URL + '/admin/video-abuses/' + videoAbuse.id
}

function getVideoViewActivityPubUrl (byActor: ActorModel, video: VideoModel) {


+ 1
- 1
server/lib/activitypub/videos.ts View File

@@ -19,7 +19,6 @@ import { logger } from '../../helpers/logger'
import { doRequest, downloadImage } from '../../helpers/requests'
import {
ACTIVITY_PUB,
CONFIG,
MIMETYPES,
P2P_MEDIA_LOADER_PEER_VERSION,
REMOTE_SCHEME,
@@ -51,6 +50,7 @@ import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
import { AccountVideoRateModel } from '../../models/account/account-video-rate'
import { VideoShareModel } from '../../models/video/video-share'
import { VideoCommentModel } from '../../models/video/video-comment'
import { CONFIG } from '../../initializers/config'

async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) {
// If the video is not private and is published, we federate it


+ 2
- 1
server/lib/avatar.ts View File

@@ -1,6 +1,6 @@
import 'multer'
import { sendUpdateActor } from './activitypub/send'
import { AVATARS_SIZE, CONFIG, sequelizeTypescript } from '../initializers'
import { AVATARS_SIZE, sequelizeTypescript } from '../initializers'
import { updateActorAvatarInstance } from './activitypub'
import { processImage } from '../helpers/image-utils'
import { AccountModel } from '../models/account/account'
@@ -8,6 +8,7 @@ import { VideoChannelModel } from '../models/video/video-channel'
import { extname, join } from 'path'
import { retryTransactionWrapper } from '../helpers/database-utils'
import * as uuidv4 from 'uuid/v4'
import { CONFIG } from '../initializers/config'

async function updateActorAvatarFile (avatarPhysicalFile: Express.Multer.File, accountOrChannel: AccountModel | VideoChannelModel) {
const extension = extname(avatarPhysicalFile.filename)


+ 7
- 6
server/lib/client-html.ts View File

@@ -1,6 +1,6 @@
import * as express from 'express'
import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/models/i18n/i18n'
import { CONFIG, CUSTOM_HTML_TAG_COMMENTS, EMBED_SIZE } from '../initializers'
import { CUSTOM_HTML_TAG_COMMENTS, EMBED_SIZE, WEBSERVER } from '../initializers'
import { join } from 'path'
import { escapeHTML } from '../helpers/core-utils'
import { VideoModel } from '../models/video/video'
@@ -11,6 +11,7 @@ import { getActivityStreamDuration } from '../models/video/video-format-utils'
import { AccountModel } from '../models/account/account'
import { VideoChannelModel } from '../models/video/video-channel'
import * as Bluebird from 'bluebird'
import { CONFIG } from '../initializers/config'

export class ClientHtml {

@@ -106,7 +107,7 @@ export class ClientHtml {

// Save locale in cookies
res.cookie('clientLanguage', lang, {
secure: CONFIG.WEBSERVER.SCHEME === 'https',
secure: WEBSERVER.SCHEME === 'https',
sameSite: true,
maxAge: 1000 * 3600 * 24 * 90 // 3 months
})
@@ -143,12 +144,12 @@ export class ClientHtml {
}

private static addVideoOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoModel) {
const previewUrl = CONFIG.WEBSERVER.URL + video.getPreviewStaticPath()
const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath()
const previewUrl = WEBSERVER.URL + video.getPreviewStaticPath()
const videoUrl = WEBSERVER.URL + video.getWatchStaticPath()

const videoNameEscaped = escapeHTML(video.name)
const videoDescriptionEscaped = escapeHTML(video.description)
const embedUrl = CONFIG.WEBSERVER.URL + video.getEmbedStaticPath()
const embedUrl = WEBSERVER.URL + video.getEmbedStaticPath()

const openGraphMetaTags = {
'og:type': 'video',
@@ -180,7 +181,7 @@ export class ClientHtml {
const oembedLinkTags = [
{
type: 'application/json+oembed',
href: CONFIG.WEBSERVER.URL + '/services/oembed?url=' + encodeURIComponent(videoUrl),
href: WEBSERVER.URL + '/services/oembed?url=' + encodeURIComponent(videoUrl),
title: videoNameEscaped
}
]


+ 22
- 21
server/lib/emailer.ts View File

@@ -1,7 +1,7 @@
import { createTransport, Transporter } from 'nodemailer'
import { isTestInstance } from '../helpers/core-utils'
import { bunyanLogger, logger } from '../helpers/logger'
import { CONFIG } from '../initializers'
import { CONFIG } from '../initializers/config'
import { UserModel } from '../models/account/user'
import { VideoModel } from '../models/video/video'
import { JobQueue } from './job-queue'
@@ -12,6 +12,7 @@ import { VideoAbuseModel } from '../models/video/video-abuse'
import { VideoBlacklistModel } from '../models/video/video-blacklist'
import { VideoImportModel } from '../models/video/video-import'
import { ActorFollowModel } from '../models/activitypub/actor-follow'
import { WEBSERVER } from '../initializers/constants'

type SendEmailOptions = {
to: string[]
@@ -91,7 +92,7 @@ class Emailer {

addNewVideoFromSubscriberNotification (to: string[], video: VideoModel) {
const channelName = video.VideoChannel.getDisplayName()
const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath()
const videoUrl = WEBSERVER.URL + video.getWatchStaticPath()

const text = `Hi dear user,\n\n` +
`Your subscription ${channelName} just published a new video: ${video.name}` +
@@ -148,7 +149,7 @@ class Emailer {
}

myVideoPublishedNotification (to: string[], video: VideoModel) {
const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath()
const videoUrl = WEBSERVER.URL + video.getWatchStaticPath()

const text = `Hi dear user,\n\n` +
`Your video ${video.name} has been published.` +
@@ -168,7 +169,7 @@ class Emailer {
}

myVideoImportSuccessNotification (to: string[], videoImport: VideoImportModel) {
const videoUrl = CONFIG.WEBSERVER.URL + videoImport.Video.getWatchStaticPath()
const videoUrl = WEBSERVER.URL + videoImport.Video.getWatchStaticPath()

const text = `Hi dear user,\n\n` +
`Your video import ${videoImport.getTargetIdentifier()} is finished.` +
@@ -188,7 +189,7 @@ class Emailer {
}

myVideoImportErrorNotification (to: string[], videoImport: VideoImportModel) {
const importUrl = CONFIG.WEBSERVER.URL + '/my-account/video-imports'
const importUrl = WEBSERVER.URL + '/my-account/video-imports'

const text = `Hi dear user,\n\n` +
`Your video import ${videoImport.getTargetIdentifier()} encountered an error.` +
@@ -210,7 +211,7 @@ class Emailer {
addNewCommentOnMyVideoNotification (to: string[], comment: VideoCommentModel) {
const accountName = comment.Account.getDisplayName()
const video = comment.Video
const commentUrl = CONFIG.WEBSERVER.URL + comment.getCommentStaticPath()
const commentUrl = WEBSERVER.URL + comment.getCommentStaticPath()

const text = `Hi dear user,\n\n` +
`A new comment has been posted by ${accountName} on your video ${video.name}` +
@@ -232,7 +233,7 @@ class Emailer {