From 6321cbc3e7a43257b03b3285ab69b7977fd7f616 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 8 Oct 2018 11:58:18 +0200 Subject: Avoid old issue regarding duplicated hosts in db --- server/initializers/migrations/0275-video-file-unique.ts | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'server/initializers') diff --git a/server/initializers/migrations/0275-video-file-unique.ts b/server/initializers/migrations/0275-video-file-unique.ts index fd89188c0..e321ecb04 100644 --- a/server/initializers/migrations/0275-video-file-unique.ts +++ b/server/initializers/migrations/0275-video-file-unique.ts @@ -5,6 +5,12 @@ async function up (utils: { queryInterface: Sequelize.QueryInterface sequelize: Sequelize.Sequelize }): Promise { + // Delete duplicated keys + { + const query = 'DELETE FROM "server" s1 USING "server" s2 WHERE s1.id < s2.id AND s1."host" = s2."host"' + await utils.sequelize.query(query) + } + { const query = 'DELETE FROM "videoFile" vf1 USING "videoFile" vf2 WHERE vf1.id < vf2.id ' + 'AND vf1."videoId" = vf2."videoId" AND vf1.resolution = vf2.resolution AND vf1.fps IS NULL' -- cgit v1.2.3 From edb4ffc7e0b13659d7c73b120f2c87b27e4c26a1 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 8 Oct 2018 09:26:04 -0500 Subject: Set bitrate limits for transcoding (fixes #638) (#1135) * Set bitrate limits for transcoding (fixes #638) * added optimization script and test, changed stuff * fix test, improve docs * re-add optimize-old-videos script * added documentation * Don't optimize videos without valid UUID, or redundancy videos * move getUUIDFromFilename * fix tests? * update torrent and file size, some more fixes/improvements * use higher bitrate for high fps video, adjust bitrates * add test video * don't throw error if resolution is undefined * generate test fixture on the fly * use random noise video for bitrate test, add promise * shorten test video to avoid timeout * use existing function to optimize video * various fixes * increase test timeout * limit test fixture size, add link * test fixes * add await * more test fixes, add -b:v parameter * replace ffmpeg wiki link * fix ffmpeg params * fix unit test * add test fixture to .gitgnore * add video transcoding fps model * add missing file --- server/initializers/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 1a3b52015..a3e5f5dd2 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -3,7 +3,7 @@ import { dirname, join } from 'path' import { JobType, VideoRateType, VideoState, VideosRedundancy } from '../../shared/models' import { ActivityPubActorType } from '../../shared/models/activitypub' import { FollowState } from '../../shared/models/actors' -import { VideoAbuseState, VideoImportState, VideoPrivacy } from '../../shared/models/videos' +import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } from '../../shared/models/videos' // Do not use barrels, remain constants as independent as possible import { buildPath, isTestInstance, parseDuration, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils' import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' @@ -393,7 +393,7 @@ const RATES_LIMIT = { } let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour -const VIDEO_TRANSCODING_FPS = { +const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = { MIN: 10, AVERAGE: 30, MAX: 60, -- cgit v1.2.3 From 0e5ff97f6fdf9a4cebe5a15f5a390380465803ad Mon Sep 17 00:00:00 2001 From: BRAINS YUM <43896676+McFlat@users.noreply.github.com> Date: Sat, 13 Oct 2018 01:43:55 -0500 Subject: add parseBytes utility function and tests (#1239) * add parseBytes utility function and tests make it parse TB MB fix parseBytes; * 1024 test bytes too, and make parseByte to parse quotas add test in travis.sh in misc * fix parseBytes and test to pass linting --- server/initializers/constants.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index a3e5f5dd2..e08fd75cd 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -5,7 +5,7 @@ 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, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils' +import { buildPath, isTestInstance, parseDuration, parseBytes, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils' import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' import { invert } from 'lodash' import { CronRepeatOptions, EveryRepeatOptions } from 'bull' @@ -232,8 +232,8 @@ const CONFIG = { } }, USER: { - get VIDEO_QUOTA () { return config.get('user.video_quota') }, - get VIDEO_QUOTA_DAILY () { return config.get('user.video_quota_daily') } + get VIDEO_QUOTA () { return parseBytes(config.get('user.video_quota')) }, + get VIDEO_QUOTA_DAILY () { return parseBytes(config.get('user.video_quota_daily')) } }, TRANSCODING: { get ENABLED () { return config.get('transcoding.enabled') }, -- cgit v1.2.3 From 64cc5e8575fda47b281ae20abf0020e27fc8ce7c Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Fri, 5 Oct 2018 15:17:34 +0200 Subject: add webtorrent opt-out settings - add a key in localstorage to remember the opt-out - add a user setting --- server/initializers/constants.ts | 10 ++++++++- .../migrations/0280-webtorrent-policy-user.ts | 26 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0280-webtorrent-policy-user.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index e08fd75cd..f56763a16 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -7,6 +7,7 @@ import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } // Do not use barrels, remain constants as independent as possible import { buildPath, isTestInstance, parseDuration, parseBytes, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils' import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' +import { WebTorrentPolicyType } from '../../shared/models/users/user-webtorrent-policy.type' import { invert } from 'lodash' import { CronRepeatOptions, EveryRepeatOptions } from 'bull' import * as bytes from 'bytes' @@ -16,7 +17,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 275 +const LAST_MIGRATION_VERSION = 280 // --------------------------------------------------------------------------- @@ -546,6 +547,12 @@ const NSFW_POLICY_TYPES: { [ id: string]: NSFWPolicyType } = { DISPLAY: 'display' } +const WEBTORRENT_POLICY_TYPES: { [ id: string]: WebTorrentPolicyType } = { + ENABLE: 'enable', + DISABLE: 'disable', + DISABLE_ON_MOBILE: 'disable_on_mobile' +} + // --------------------------------------------------------------------------- // Express static paths (router) @@ -698,6 +705,7 @@ export { FEEDS, JOB_TTL, NSFW_POLICY_TYPES, + WEBTORRENT_POLICY_TYPES, TORRENT_MIMETYPE_EXT, STATIC_MAX_AGE, STATIC_PATHS, diff --git a/server/initializers/migrations/0280-webtorrent-policy-user.ts b/server/initializers/migrations/0280-webtorrent-policy-user.ts new file mode 100644 index 000000000..d24f6709e --- /dev/null +++ b/server/initializers/migrations/0280-webtorrent-policy-user.ts @@ -0,0 +1,26 @@ +import * as Sequelize from 'sequelize' +import { values } from 'lodash' +import { WEBTORRENT_POLICY_TYPES } from '../constants' + +async function up (utils: { + transaction: Sequelize.Transaction + queryInterface: Sequelize.QueryInterface + sequelize: Sequelize.Sequelize +}): Promise { + { + const data = { + type: Sequelize.ENUM(values(WEBTORRENT_POLICY_TYPES)), + allowNull: false, + defaultValue: 'enable' + } + + await utils.queryInterface.addColumn('user', 'webTorrentPolicy', data) + } + +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { up, down } -- cgit v1.2.3 From ed638e5325096ef580da20f370ac61c59cd48cf7 Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Fri, 12 Oct 2018 18:12:39 +0200 Subject: move to boolean switch --- server/initializers/constants.ts | 8 -------- .../migrations/0280-webtorrent-policy-user.ts | 16 +++++++++------- 2 files changed, 9 insertions(+), 15 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index f56763a16..c3e4fcede 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -7,7 +7,6 @@ import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } // Do not use barrels, remain constants as independent as possible import { buildPath, isTestInstance, parseDuration, parseBytes, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils' import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' -import { WebTorrentPolicyType } from '../../shared/models/users/user-webtorrent-policy.type' import { invert } from 'lodash' import { CronRepeatOptions, EveryRepeatOptions } from 'bull' import * as bytes from 'bytes' @@ -547,12 +546,6 @@ const NSFW_POLICY_TYPES: { [ id: string]: NSFWPolicyType } = { DISPLAY: 'display' } -const WEBTORRENT_POLICY_TYPES: { [ id: string]: WebTorrentPolicyType } = { - ENABLE: 'enable', - DISABLE: 'disable', - DISABLE_ON_MOBILE: 'disable_on_mobile' -} - // --------------------------------------------------------------------------- // Express static paths (router) @@ -705,7 +698,6 @@ export { FEEDS, JOB_TTL, NSFW_POLICY_TYPES, - WEBTORRENT_POLICY_TYPES, TORRENT_MIMETYPE_EXT, STATIC_MAX_AGE, STATIC_PATHS, diff --git a/server/initializers/migrations/0280-webtorrent-policy-user.ts b/server/initializers/migrations/0280-webtorrent-policy-user.ts index d24f6709e..e6488356a 100644 --- a/server/initializers/migrations/0280-webtorrent-policy-user.ts +++ b/server/initializers/migrations/0280-webtorrent-policy-user.ts @@ -1,6 +1,4 @@ import * as Sequelize from 'sequelize' -import { values } from 'lodash' -import { WEBTORRENT_POLICY_TYPES } from '../constants' async function up (utils: { transaction: Sequelize.Transaction @@ -9,18 +7,22 @@ async function up (utils: { }): Promise { { const data = { - type: Sequelize.ENUM(values(WEBTORRENT_POLICY_TYPES)), + type: Sequelize.BOOLEAN, allowNull: false, - defaultValue: 'enable' + defaultValue: true } - await utils.queryInterface.addColumn('user', 'webTorrentPolicy', data) + await utils.queryInterface.addColumn('user', 'webTorrentEnabled', data) } } -function down (options) { - throw new Error('Not implemented.') +async function down (utils: { + transaction: Sequelize.Transaction + queryInterface: Sequelize.QueryInterface + sequelize: Sequelize.Sequelize +}): Promise { + await utils.queryInterface.removeColumn('user', 'webTorrentEnabled') } export { up, down } -- cgit v1.2.3 From 6f2ae7a1aa1b4a8b5605fc4c57c0c1d1fbe2a16e Mon Sep 17 00:00:00 2001 From: Adnane Belmadiaf Date: Sun, 14 Oct 2018 19:43:17 +0200 Subject: rename News category into News & Politics (#1261) --- server/initializers/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index e08fd75cd..49ee13c10 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -421,7 +421,7 @@ const VIDEO_CATEGORIES = { 8: 'People', 9: 'Comedy', 10: 'Entertainment', - 11: 'News', + 11: 'News & Politics', 12: 'How To', 13: 'Education', 14: 'Activism', -- cgit v1.2.3 From 7ad9b9846c44d198a736183fb186c2039f5236b5 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 12 Oct 2018 15:26:04 +0200 Subject: Add ability for users to block an account/instance on server side --- server/initializers/constants.ts | 5 ++++- server/initializers/database.ts | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 49ee13c10..cf00da2c7 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -47,7 +47,10 @@ const SORTABLE_COLUMNS = { VIDEOS: [ 'name', 'duration', 'createdAt', 'publishedAt', 'views', 'likes', 'trending' ], VIDEOS_SEARCH: [ 'name', 'duration', 'createdAt', 'publishedAt', 'views', 'likes', 'match' ], - VIDEO_CHANNELS_SEARCH: [ 'match', 'displayName', 'createdAt' ] + VIDEO_CHANNELS_SEARCH: [ 'match', 'displayName', 'createdAt' ], + + ACCOUNTS_BLOCKLIST: [ 'createdAt' ], + SERVERS_BLOCKLIST: [ 'createdAt' ] } const OAUTH_LIFETIME = { diff --git a/server/initializers/database.ts b/server/initializers/database.ts index 482c03b31..dd5b9bf67 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts @@ -29,6 +29,8 @@ import { VideoViewModel } from '../models/video/video-views' import { VideoChangeOwnershipModel } from '../models/video/video-change-ownership' import { VideoRedundancyModel } from '../models/redundancy/video-redundancy' import { UserVideoHistoryModel } from '../models/account/user-video-history' +import { AccountBlocklistModel } from '../models/account/account-blocklist' +import { ServerBlocklistModel } from '../models/server/server-blocklist' require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string @@ -91,7 +93,9 @@ async function initDatabaseModels (silent: boolean) { VideoImportModel, VideoViewModel, VideoRedundancyModel, - UserVideoHistoryModel + UserVideoHistoryModel, + AccountBlocklistModel, + ServerBlocklistModel ]) // Check extensions exist in the database -- cgit v1.2.3 From cdf4cb9eaf5f6bc71f7c1e1963c07575f1d2593d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 18 Oct 2018 09:44:43 +0200 Subject: Fix transcoding --- server/initializers/checker-before-init.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index 4f46d406a..9dfb5d68c 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts @@ -77,7 +77,7 @@ async function checkFFmpeg (CONFIG: { TRANSCODING: { ENABLED: boolean } }) { } } - checkFFmpegEncoders() + return checkFFmpegEncoders() } // Optional encoders, if present, can be used to improve transcoding @@ -95,10 +95,10 @@ async function checkFFmpegEncoders (): Promise> { supportedOptionalEncoders = new Map() for (const encoder of optionalEncoders) { - supportedOptionalEncoders.set(encoder, - encoders[encoder] !== undefined - ) + supportedOptionalEncoders.set(encoder, encoders[encoder] !== undefined) } + + return supportedOptionalEncoders } // --------------------------------------------------------------------------- -- cgit v1.2.3 From d23e6a1c97a6ae3ca8d340a8c9adad268a5be57e Mon Sep 17 00:00:00 2001 From: BRAINS YUM <43896676+McFlat@users.noreply.github.com> Date: Fri, 19 Oct 2018 01:54:01 -0500 Subject: Feature/description support fields length 1000 (#1267) * fix migrations to not use config constant values as it can introduce bugs later when they change; (fixes #1259) remove constant fields imports from migrations * add migrations to update description and support fields to 1000 (fixes #1258) * fix client/server account and video_channel description/support fields to be max len 1000 (fixes #1258); fix test Should fail with a too long description; fix test Should fail with a long description; fix test Should fail with a long description; Remove USER.SUPPORT from constants since that field no longer exists; null not false, in migrations/0280-description-support.ts; video support field 1000, oops; * rename migration 0280-description-support.ts -> 0285-description-support.ts; update video support maxlength text --- server/initializers/constants.ts | 10 ++-- server/initializers/migrations/0120-video-null.ts | 3 +- server/initializers/migrations/0195-support.ts | 9 ++-- .../initializers/migrations/0245-user-blocked.ts | 3 +- .../migrations/0250-video-abuse-state.ts | 3 +- .../migrations/0255-video-blacklist-reason.ts | 3 +- .../migrations/0260-upload-quota-daily.ts | 1 - .../migrations/0285-description-support.ts | 53 ++++++++++++++++++++++ 8 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 server/initializers/migrations/0285-description-support.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 03158e356..e8843a3ab 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 280 +const LAST_MIGRATION_VERSION = 285 // --------------------------------------------------------------------------- @@ -295,7 +295,7 @@ const CONFIG = { const CONSTRAINTS_FIELDS = { USERS: { NAME: { min: 3, max: 120 }, // Length - DESCRIPTION: { min: 3, max: 250 }, // Length + DESCRIPTION: { min: 3, max: 1000 }, // Length USERNAME: { min: 3, max: 20 }, // Length PASSWORD: { min: 6, max: 255 }, // Length VIDEO_QUOTA: { min: -1 }, @@ -311,8 +311,8 @@ const CONSTRAINTS_FIELDS = { }, VIDEO_CHANNELS: { NAME: { min: 3, max: 120 }, // Length - DESCRIPTION: { min: 3, max: 500 }, // Length - SUPPORT: { min: 3, max: 500 }, // Length + DESCRIPTION: { min: 3, max: 1000 }, // Length + SUPPORT: { min: 3, max: 1000 }, // Length URL: { min: 3, max: 2000 } // Length }, VIDEO_CAPTIONS: { @@ -341,7 +341,7 @@ const CONSTRAINTS_FIELDS = { LANGUAGE: { min: 1, max: 10 }, // Length TRUNCATED_DESCRIPTION: { min: 3, max: 250 }, // Length DESCRIPTION: { min: 3, max: 10000 }, // Length - SUPPORT: { min: 3, max: 500 }, // Length + SUPPORT: { min: 3, max: 1000 }, // Length IMAGE: { EXTNAME: [ '.jpg', '.jpeg' ], FILE_SIZE: { diff --git a/server/initializers/migrations/0120-video-null.ts b/server/initializers/migrations/0120-video-null.ts index 63f3984dd..6d253f04f 100644 --- a/server/initializers/migrations/0120-video-null.ts +++ b/server/initializers/migrations/0120-video-null.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import { CONSTRAINTS_FIELDS } from '../constants' async function up (utils: { transaction: Sequelize.Transaction, @@ -28,7 +27,7 @@ async function up (utils: { { const data = { - type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max), + type: Sequelize.STRING(10000), allowNull: true, defaultValue: null } diff --git a/server/initializers/migrations/0195-support.ts b/server/initializers/migrations/0195-support.ts index 8722a5f22..3b9eabe79 100644 --- a/server/initializers/migrations/0195-support.ts +++ b/server/initializers/migrations/0195-support.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import { CONSTRAINTS_FIELDS } from '../index' async function up (utils: { transaction: Sequelize.Transaction, @@ -8,7 +7,7 @@ async function up (utils: { }): Promise { { const data = { - type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEOS.SUPPORT.max), + type: Sequelize.STRING(500), allowNull: true, defaultValue: null } @@ -17,7 +16,7 @@ async function up (utils: { { const data = { - type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.SUPPORT.max), + type: Sequelize.STRING(500), allowNull: true, defaultValue: null } @@ -26,7 +25,7 @@ async function up (utils: { { const data = { - type: Sequelize.STRING(CONSTRAINTS_FIELDS.USERS.DESCRIPTION.max), + type: Sequelize.STRING(250), allowNull: true, defaultValue: null } @@ -35,7 +34,7 @@ async function up (utils: { { const data = { - type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max), + type: Sequelize.STRING(10000), allowNull: true, defaultValue: null } diff --git a/server/initializers/migrations/0245-user-blocked.ts b/server/initializers/migrations/0245-user-blocked.ts index 5a04ecd2b..19c7d5b9c 100644 --- a/server/initializers/migrations/0245-user-blocked.ts +++ b/server/initializers/migrations/0245-user-blocked.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import { CONSTRAINTS_FIELDS } from '../constants' async function up (utils: { transaction: Sequelize.Transaction @@ -31,7 +30,7 @@ async function up (utils: { { const data = { - type: Sequelize.STRING(CONSTRAINTS_FIELDS.USERS.BLOCKED_REASON.max), + type: Sequelize.STRING(250), allowNull: true, defaultValue: null } diff --git a/server/initializers/migrations/0250-video-abuse-state.ts b/server/initializers/migrations/0250-video-abuse-state.ts index acb668ae1..50de25182 100644 --- a/server/initializers/migrations/0250-video-abuse-state.ts +++ b/server/initializers/migrations/0250-video-abuse-state.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import { CONSTRAINTS_FIELDS } from '../constants' import { VideoAbuseState } from '../../../shared/models/videos' async function up (utils: { @@ -32,7 +31,7 @@ async function up (utils: { { const data = { - type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.MODERATION_COMMENT.max), + type: Sequelize.STRING(300), allowNull: true, defaultValue: null } diff --git a/server/initializers/migrations/0255-video-blacklist-reason.ts b/server/initializers/migrations/0255-video-blacklist-reason.ts index a380e620e..69d6efb9e 100644 --- a/server/initializers/migrations/0255-video-blacklist-reason.ts +++ b/server/initializers/migrations/0255-video-blacklist-reason.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import { CONSTRAINTS_FIELDS } from '../constants' import { VideoAbuseState } from '../../../shared/models/videos' async function up (utils: { @@ -10,7 +9,7 @@ async function up (utils: { { const data = { - type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEO_BLACKLIST.REASON.max), + type: Sequelize.STRING(300), allowNull: true, defaultValue: null } diff --git a/server/initializers/migrations/0260-upload-quota-daily.ts b/server/initializers/migrations/0260-upload-quota-daily.ts index d25154ba6..cbbe391ef 100644 --- a/server/initializers/migrations/0260-upload-quota-daily.ts +++ b/server/initializers/migrations/0260-upload-quota-daily.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import { CONSTRAINTS_FIELDS } from '../constants' async function up (utils: { transaction: Sequelize.Transaction diff --git a/server/initializers/migrations/0285-description-support.ts b/server/initializers/migrations/0285-description-support.ts new file mode 100644 index 000000000..85ef4ef39 --- /dev/null +++ b/server/initializers/migrations/0285-description-support.ts @@ -0,0 +1,53 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize, + db: any +}): Promise { + { + const data = { + type: Sequelize.STRING(1000), + allowNull: true, + defaultValue: null + } + await utils.queryInterface.changeColumn('video', 'support', data) + } + + { + const data = { + type: Sequelize.STRING(1000), + allowNull: true, + defaultValue: null + } + await utils.queryInterface.changeColumn('videoChannel', 'support', data) + } + + { + const data = { + type: Sequelize.STRING(1000), + allowNull: true, + defaultValue: null + } + await utils.queryInterface.changeColumn('videoChannel', 'description', data) + } + + { + const data = { + type: Sequelize.STRING(1000), + allowNull: true, + defaultValue: null + } + await utils.queryInterface.changeColumn('account', 'description', data) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From 41f2ebae4f970932fb62d2d8923b1f776f0b1494 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 19 Oct 2018 11:41:19 +0200 Subject: Add HTTP signature check before linked signature It's faster, and will allow us to use RSA signature 2018 (with upstream jsonld-signature module) without too much incompatibilities in the peertube federation --- server/initializers/constants.ts | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index e8843a3ab..28d51068b 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -532,6 +532,12 @@ const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = { APPLICATION: 'Application' } +const HTTP_SIGNATURE = { + HEADER_NAME: 'signature', + ALGORITHM: 'rsa-sha256', + HEADERS_TO_SIGN: [ 'date', 'host', 'digest', '(request-target)' ] +} + // --------------------------------------------------------------------------- const PRIVATE_RSA_KEY_SIZE = 2048 @@ -731,6 +737,7 @@ export { VIDEO_EXT_MIMETYPE, CRAWL_REQUEST_CONCURRENCY, JOB_COMPLETED_LIFETIME, + HTTP_SIGNATURE, VIDEO_IMPORT_STATES, VIDEO_VIEW_LIFETIME, buildLanguages -- cgit v1.2.3 From df66d81583e07ce049daeeef1edc6a87b57b3684 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 23 Oct 2018 11:38:48 +0200 Subject: Add compatibility with other Linked Signature algorithms --- server/initializers/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 28d51068b..9aadbe824 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -535,7 +535,7 @@ const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = { const HTTP_SIGNATURE = { HEADER_NAME: 'signature', ALGORITHM: 'rsa-sha256', - HEADERS_TO_SIGN: [ 'date', 'host', 'digest', '(request-target)' ] + HEADERS_TO_SIGN: [ '(request-target)', 'host', 'date', 'digest' ] } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 5c6d985faeef1d6793d3f44ca6374f1a9b722806 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 14 Nov 2018 15:01:28 +0100 Subject: Check activities host --- server/initializers/constants.ts | 5 ++- .../migrations/0290-account-video-rate-url.ts | 46 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0290-account-video-rate-url.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 9aadbe824..ae3d671bb 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 285 +const LAST_MIGRATION_VERSION = 290 // --------------------------------------------------------------------------- @@ -336,6 +336,9 @@ const CONSTRAINTS_FIELDS = { VIDEOS_REDUNDANCY: { URL: { min: 3, max: 2000 } // Length }, + VIDEO_RATES: { + URL: { min: 3, max: 2000 } // Length + }, VIDEOS: { NAME: { min: 3, max: 120 }, // Length LANGUAGE: { min: 1, max: 10 }, // Length diff --git a/server/initializers/migrations/0290-account-video-rate-url.ts b/server/initializers/migrations/0290-account-video-rate-url.ts new file mode 100644 index 000000000..bdabf2929 --- /dev/null +++ b/server/initializers/migrations/0290-account-video-rate-url.ts @@ -0,0 +1,46 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize, + db: any +}): Promise { + { + const data = { + type: Sequelize.STRING(2000), + allowNull: true + } + + await utils.queryInterface.addColumn('accountVideoRate', 'url', data) + } + + { + const builtUrlQuery = `SELECT "actor"."url" || '/' || "accountVideoRate"."type" || 's/' || "videoId" ` + + 'FROM "accountVideoRate" ' + + 'INNER JOIN account ON account.id = "accountVideoRate"."accountId" ' + + 'INNER JOIN actor ON actor.id = account."actorId" ' + + 'WHERE "base".id = "accountVideoRate".id' + + const query = 'UPDATE "accountVideoRate" base SET "url" = (' + builtUrlQuery + ') WHERE "url" IS NULL' + await utils.sequelize.query(query) + } + + { + const data = { + type: Sequelize.STRING(2000), + allowNull: false, + defaultValue: null + } + await utils.queryInterface.changeColumn('accountVideoRate', 'url', data) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From 0b2f03d3712f438f67eccf86b67acd047284f9b4 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 19 Nov 2018 15:21:09 +0100 Subject: Speedup peertube startup --- server/initializers/database.ts | 32 +++++++++++++++++--------------- server/initializers/installer.ts | 21 +++++++++++++++------ 2 files changed, 32 insertions(+), 21 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/database.ts b/server/initializers/database.ts index dd5b9bf67..40cd659ab 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts @@ -119,25 +119,27 @@ export { // --------------------------------------------------------------------------- async function checkPostgresExtensions () { - const extensions = [ - 'pg_trgm', - 'unaccent' + const promises = [ + checkPostgresExtension('pg_trgm'), + checkPostgresExtension('unaccent') ] - for (const extension of extensions) { - const query = `SELECT true AS enabled FROM pg_available_extensions WHERE name = '${extension}' AND installed_version IS NOT NULL;` - const [ res ] = await sequelizeTypescript.query(query, { raw: true }) + return Promise.all(promises) +} + +async function checkPostgresExtension (extension: string) { + const query = `SELECT true AS enabled FROM pg_available_extensions WHERE name = '${extension}' AND installed_version IS NOT NULL;` + const [ res ] = await sequelizeTypescript.query(query, { raw: true }) - if (!res || res.length === 0 || res[ 0 ][ 'enabled' ] !== true) { - // Try to create the extension ourself - try { - await sequelizeTypescript.query(`CREATE EXTENSION ${extension};`, { raw: true }) + if (!res || res.length === 0 || res[ 0 ][ 'enabled' ] !== true) { + // Try to create the extension ourself + try { + await sequelizeTypescript.query(`CREATE EXTENSION ${extension};`, { raw: true }) - } catch { - const errorMessage = `You need to enable ${extension} extension in PostgreSQL. ` + - `You can do so by running 'CREATE EXTENSION ${extension};' as a PostgreSQL super user in ${CONFIG.DATABASE.DBNAME} database.` - throw new Error(errorMessage) - } + } catch { + const errorMessage = `You need to enable ${extension} extension in PostgreSQL. ` + + `You can do so by running 'CREATE EXTENSION ${extension};' as a PostgreSQL super user in ${CONFIG.DATABASE.DBNAME} database.` + throw new Error(errorMessage) } } } diff --git a/server/initializers/installer.ts b/server/initializers/installer.ts index c952ad46c..b9a9da183 100644 --- a/server/initializers/installer.ts +++ b/server/initializers/installer.ts @@ -12,12 +12,21 @@ import { remove, ensureDir } from 'fs-extra' async function installApplication () { try { - await sequelizeTypescript.sync() - await removeCacheDirectories() - await createDirectoriesIfNotExist() - await createApplicationIfNotExist() - await createOAuthClientIfNotExist() - await createOAuthAdminIfNotExist() + await Promise.all([ + // Database related + sequelizeTypescript.sync() + .then(() => { + return Promise.all([ + createApplicationIfNotExist(), + createOAuthClientIfNotExist(), + createOAuthAdminIfNotExist() + ]) + }), + + // Directories + removeCacheDirectories() + .then(() => createDirectoriesIfNotExist()) + ]) } catch (err) { logger.error('Cannot install application.', { err }) process.exit(-1) -- cgit v1.2.3 From 04b8c3fba614efc3827f583096c78b08cb668470 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 20 Nov 2018 10:05:51 +0100 Subject: Delete invalid or deleted remote videos --- server/initializers/constants.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index ae3d671bb..aa243859c 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -102,7 +102,8 @@ const JOB_ATTEMPTS: { [ id in JobType ]: number } = { 'video-file': 1, 'video-import': 1, 'email': 5, - 'videos-views': 1 + 'videos-views': 1, + 'activitypub-refresher': 1 } const JOB_CONCURRENCY: { [ id in JobType ]: number } = { 'activitypub-http-broadcast': 1, @@ -113,7 +114,8 @@ const JOB_CONCURRENCY: { [ id in JobType ]: number } = { 'video-file': 1, 'video-import': 1, 'email': 5, - 'videos-views': 1 + 'videos-views': 1, + 'activitypub-refresher': 1 } const JOB_TTL: { [ id in JobType ]: number } = { 'activitypub-http-broadcast': 60000 * 10, // 10 minutes @@ -124,11 +126,12 @@ const JOB_TTL: { [ id in JobType ]: number } = { 'video-file': 1000 * 3600 * 48, // 2 days, transcoding could be long 'video-import': 1000 * 3600 * 2, // hours 'email': 60000 * 10, // 10 minutes - 'videos-views': undefined // Unlimited + 'videos-views': undefined, // Unlimited + 'activitypub-refresher': 60000 * 10 // 10 minutes } const REPEAT_JOBS: { [ id: string ]: EveryRepeatOptions | CronRepeatOptions } = { 'videos-views': { - cron: '1 * * * *' // At 1 minutes past the hour + cron: '1 * * * *' // At 1 minute past the hour } } @@ -543,7 +546,7 @@ const HTTP_SIGNATURE = { // --------------------------------------------------------------------------- -const PRIVATE_RSA_KEY_SIZE = 2048 +let PRIVATE_RSA_KEY_SIZE = 2048 // Password encryption const BCRYPT_SALT_SIZE = 10 @@ -647,6 +650,8 @@ const TRACKER_RATE_LIMITS = { // Special constants for a test instance if (isTestInstance() === true) { + PRIVATE_RSA_KEY_SIZE = 1024 + ACTOR_FOLLOW_SCORE.BASE = 20 REMOTE_SCHEME.HTTP = 'http' -- cgit v1.2.3 From f9a971c671d5a8b88f420a86656a788575105598 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 4 Dec 2018 09:34:29 +0100 Subject: Update dependencies --- server/initializers/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index aa243859c..8a8bcd126 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -773,7 +773,7 @@ function buildVideosRedundancy (objs: any[]): VideosRedundancy[] { if (!objs) return [] return objs.map(obj => { - return Object.assign(obj, { + return Object.assign({}, obj, { minLifetime: parseDuration(obj.min_lifetime), size: bytes.parse(obj.size), minViews: obj.min_views -- cgit v1.2.3 From 6040f87d143a5fa01db79867ece8197c3ce7be47 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 4 Dec 2018 16:02:49 +0100 Subject: Add tmp and redundancy directories --- server/initializers/checker-before-init.ts | 1 + server/initializers/constants.ts | 2 ++ 2 files changed, 3 insertions(+) (limited to 'server/initializers') diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index 9dfb5d68c..b51c7cfba 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts @@ -12,6 +12,7 @@ function checkMissedConfig () { 'database.hostname', 'database.port', 'database.suffix', 'database.username', 'database.password', 'database.pool.max', 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address', 'storage.avatars', 'storage.videos', 'storage.logs', 'storage.previews', 'storage.thumbnails', 'storage.torrents', 'storage.cache', + 'storage.redundancy', 'storage.tmp', 'log.level', 'user.video_quota', 'user.video_quota_daily', 'cache.previews.size', 'admin.email', diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 8a8bcd126..876aa1cf5 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -185,9 +185,11 @@ const CONFIG = { FROM_ADDRESS: config.get('smtp.from_address') }, STORAGE: { + TMP_DIR: buildPath(config.get('storage.tmp')), AVATARS_DIR: buildPath(config.get('storage.avatars')), LOG_DIR: buildPath(config.get('storage.logs')), VIDEOS_DIR: buildPath(config.get('storage.videos')), + REDUNDANCY_DIR: buildPath(config.get('storage.redundancy')), THUMBNAILS_DIR: buildPath(config.get('storage.thumbnails')), PREVIEWS_DIR: buildPath(config.get('storage.previews')), CAPTIONS_DIR: buildPath(config.get('storage.captions')), -- cgit v1.2.3 From b9fffa297f49a84df8ffd0d7b842599bc88a8e3e Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 4 Dec 2018 17:08:55 +0100 Subject: Create redundancy endpoint --- server/initializers/constants.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 876aa1cf5..7195ae6c5 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -571,6 +571,7 @@ const STATIC_PATHS = { THUMBNAILS: '/static/thumbnails/', TORRENTS: '/static/torrents/', WEBSEED: '/static/webseed/', + REDUNDANCY: '/static/redundancy/', AVATARS: '/static/avatars/', VIDEO_CAPTIONS: '/static/video-captions/' } -- cgit v1.2.3 From 2feebf3e6afaad9ab80976d1557d3a7bcf94de03 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 5 Dec 2018 17:27:24 +0100 Subject: Add sitemap --- server/initializers/constants.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 7195ae6c5..6b798875c 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -61,6 +61,7 @@ const OAUTH_LIFETIME = { const ROUTE_CACHE_LIFETIME = { FEEDS: '15 minutes', ROBOTS: '2 hours', + SITEMAP: '1 day', SECURITYTXT: '2 hours', NODEINFO: '10 minutes', DNT_POLICY: '1 week', -- cgit v1.2.3 From d0ce42c1c17054b7e0c5081243152c32ecb1c193 Mon Sep 17 00:00:00 2001 From: BRAINS YUM <43896676+McFlat@users.noreply.github.com> Date: Fri, 7 Dec 2018 07:54:33 -0600 Subject: username/display_name/video_channel_name min length 1 and max length 50 (#1265) * make username, display_name and video_channel_name min length 1 and max length 50; (fixes #1263); ! still some bug on the frontend complains but if you remove the disabled property it creates the account just fine; allow for usernames to start with a number; fix test, since username can be 1 char now make test check empty; fix test, Should fail with a too long username; fix test, Should fail with a too small username; fix regular expression for username and videoChannel; change username, videoChannel to be lowercase and fix message; * change 1 characters to 1 character --- server/initializers/constants.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 6b798875c..d4496bc34 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -300,9 +300,9 @@ const CONFIG = { const CONSTRAINTS_FIELDS = { USERS: { - NAME: { min: 3, max: 120 }, // Length + NAME: { min: 1, max: 50 }, // Length DESCRIPTION: { min: 3, max: 1000 }, // Length - USERNAME: { min: 3, max: 20 }, // Length + USERNAME: { min: 1, max: 50 }, // Length PASSWORD: { min: 6, max: 255 }, // Length VIDEO_QUOTA: { min: -1 }, VIDEO_QUOTA_DAILY: { min: -1 }, @@ -316,7 +316,7 @@ const CONSTRAINTS_FIELDS = { REASON: { min: 2, max: 300 } // Length }, VIDEO_CHANNELS: { - NAME: { min: 3, max: 120 }, // Length + NAME: { min: 1, max: 50 }, // Length DESCRIPTION: { min: 3, max: 1000 }, // Length SUPPORT: { min: 3, max: 1000 }, // Length URL: { min: 3, max: 2000 } // Length -- cgit v1.2.3 From 14e2014acc1362cfbb770c051a7254b156cd8efb Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 11 Dec 2018 14:52:50 +0100 Subject: Support additional video extensions --- server/initializers/checker-before-init.ts | 2 +- server/initializers/constants.ts | 96 +++++++++++++++------- .../migrations/0295-video-file-extname.ts | 49 +++++++++++ 3 files changed, 115 insertions(+), 32 deletions(-) create mode 100644 server/initializers/migrations/0295-video-file-extname.ts (limited to 'server/initializers') diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index b51c7cfba..a7bc7eec8 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts @@ -19,7 +19,7 @@ function checkMissedConfig () { 'signup.enabled', 'signup.limit', 'signup.requires_email_verification', 'signup.filters.cidr.whitelist', 'signup.filters.cidr.blacklist', 'redundancy.videos.strategies', 'redundancy.videos.check_interval', - 'transcoding.enabled', 'transcoding.threads', + 'transcoding.enabled', 'transcoding.threads', 'transcoding.allow_additional_extensions', 'import.videos.http.enabled', 'import.videos.torrent.enabled', 'trending.videos.interval_days', 'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route', diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index d4496bc34..ad61bee73 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 290 +const LAST_MIGRATION_VERSION = 295 // --------------------------------------------------------------------------- @@ -246,6 +246,7 @@ const CONFIG = { }, TRANSCODING: { get ENABLED () { return config.get('transcoding.enabled') }, + get ALLOW_ADDITIONAL_EXTENSIONS () { return config.get('transcoding.allow_additional_extensions') }, get THREADS () { return config.get('transcoding.threads') }, RESOLUTIONS: { get '240p' () { return config.get('transcoding.resolutions.240p') }, @@ -298,7 +299,7 @@ const CONFIG = { // --------------------------------------------------------------------------- -const CONSTRAINTS_FIELDS = { +let CONSTRAINTS_FIELDS = { USERS: { NAME: { min: 1, max: 50 }, // Length DESCRIPTION: { min: 3, max: 1000 }, // Length @@ -357,7 +358,7 @@ const CONSTRAINTS_FIELDS = { max: 2 * 1024 * 1024 // 2MB } }, - EXTNAME: [ '.mp4', '.ogv', '.webm' ], + EXTNAME: buildVideosExtname(), INFO_HASH: { min: 40, max: 40 }, // Length, info hash is 20 bytes length but we represent it in hexadecimal so 20 * 2 DURATION: { min: 0 }, // Number TAGS: { min: 0, max: 5 }, // Number of total tags @@ -480,27 +481,31 @@ const VIDEO_ABUSE_STATES = { [VideoAbuseState.ACCEPTED]: 'Accepted' } -const VIDEO_MIMETYPE_EXT = { - 'video/webm': '.webm', - 'video/ogg': '.ogv', - 'video/mp4': '.mp4' -} -const VIDEO_EXT_MIMETYPE = invert(VIDEO_MIMETYPE_EXT) - -const IMAGE_MIMETYPE_EXT = { - 'image/png': '.png', - 'image/jpg': '.jpg', - 'image/jpeg': '.jpg' -} - -const VIDEO_CAPTIONS_MIMETYPE_EXT = { - 'text/vtt': '.vtt', - 'application/x-subrip': '.srt' -} - -const TORRENT_MIMETYPE_EXT = { - 'application/x-bittorrent': '.torrent' +const MIMETYPES = { + VIDEO: { + MIMETYPE_EXT: buildVideoMimetypeExt(), + EXT_MIMETYPE: null as { [ id: string ]: string } + }, + IMAGE: { + MIMETYPE_EXT: { + 'image/png': '.png', + 'image/jpg': '.jpg', + 'image/jpeg': '.jpg' + } + }, + VIDEO_CAPTIONS: { + MIMETYPE_EXT: { + 'text/vtt': '.vtt', + 'application/x-subrip': '.srt' + } + }, + TORRENT: { + MIMETYPE_EXT: { + 'application/x-bittorrent': '.torrent' + } + } } +MIMETYPES.VIDEO.EXT_MIMETYPE = invert(MIMETYPES.VIDEO.MIMETYPE_EXT) // --------------------------------------------------------------------------- @@ -526,7 +531,7 @@ const ACTIVITY_PUB = { COLLECTION_ITEMS_PER_PAGE: 10, FETCH_PAGE_LIMIT: 100, URL_MIME_TYPES: { - VIDEO: Object.keys(VIDEO_MIMETYPE_EXT), + VIDEO: Object.keys(MIMETYPES.VIDEO.MIMETYPE_EXT), TORRENT: [ 'application/x-bittorrent' ], MAGNET: [ 'application/x-bittorrent;x-scheme-handler/magnet' ] }, @@ -685,13 +690,12 @@ if (isTestInstance() === true) { ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms' } -updateWebserverConfig() +updateWebserverUrls() // --------------------------------------------------------------------------- export { API_VERSION, - VIDEO_CAPTIONS_MIMETYPE_EXT, AVATARS_SIZE, ACCEPT_HEADERS, BCRYPT_SALT_SIZE, @@ -719,7 +723,6 @@ export { FEEDS, JOB_TTL, NSFW_POLICY_TYPES, - TORRENT_MIMETYPE_EXT, STATIC_MAX_AGE, STATIC_PATHS, VIDEO_IMPORT_TIMEOUT, @@ -732,7 +735,6 @@ export { VIDEO_LICENCES, VIDEO_STATES, VIDEO_RATE_TYPES, - VIDEO_MIMETYPE_EXT, VIDEO_TRANSCODING_FPS, FFMPEG_NICE, VIDEO_ABUSE_STATES, @@ -740,13 +742,12 @@ export { USER_PASSWORD_RESET_LIFETIME, MEMOIZE_TTL, USER_EMAIL_VERIFY_LIFETIME, - IMAGE_MIMETYPE_EXT, OVERVIEWS, SCHEDULER_INTERVALS_MS, REPEAT_JOBS, STATIC_DOWNLOAD_PATHS, RATES_LIMIT, - VIDEO_EXT_MIMETYPE, + MIMETYPES, CRAWL_REQUEST_CONCURRENCY, JOB_COMPLETED_LIFETIME, HTTP_SIGNATURE, @@ -768,11 +769,43 @@ function getLocalConfigFilePath () { return join(dirname(configSources[ 0 ].name), filename + '.json') } -function updateWebserverConfig () { +function buildVideoMimetypeExt () { + const data = { + 'video/webm': '.webm', + 'video/ogg': '.ogv', + 'video/mp4': '.mp4' + } + + if (CONFIG.TRANSCODING.ENABLED && CONFIG.TRANSCODING.ALLOW_ADDITIONAL_EXTENSIONS) { + Object.assign(data, { + 'video/quicktime': '.mov', + 'video/x-msvideo': '.avi', + 'video/x-flv': '.flv', + 'video/x-matroska': '.mkv' + }) + } + + return data +} + +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) } +function updateWebserverConfig () { + CONSTRAINTS_FIELDS.VIDEOS.EXTNAME = buildVideosExtname() + + MIMETYPES.VIDEO.MIMETYPE_EXT = buildVideoMimetypeExt() + MIMETYPES.VIDEO.EXT_MIMETYPE = invert(MIMETYPES.VIDEO.MIMETYPE_EXT) +} + +function buildVideosExtname () { + return CONFIG.TRANSCODING.ENABLED && CONFIG.TRANSCODING.ALLOW_ADDITIONAL_EXTENSIONS + ? [ '.mp4', '.ogv', '.webm', '.mkv', '.mov', '.avi', '.flv' ] + : [ '.mp4', '.ogv', '.webm' ] +} + function buildVideosRedundancy (objs: any[]): VideosRedundancy[] { if (!objs) return [] @@ -854,4 +887,5 @@ export function reloadConfig () { config = require('config') updateWebserverConfig() + updateWebserverUrls() } diff --git a/server/initializers/migrations/0295-video-file-extname.ts b/server/initializers/migrations/0295-video-file-extname.ts new file mode 100644 index 000000000..dbf249f66 --- /dev/null +++ b/server/initializers/migrations/0295-video-file-extname.ts @@ -0,0 +1,49 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize, + db: any +}): Promise { + { + await utils.queryInterface.renameColumn('videoFile', 'extname', 'extname_old') + } + + { + const data = { + type: Sequelize.STRING, + defaultValue: null, + allowNull: true + } + + await utils.queryInterface.addColumn('videoFile', 'extname', data) + } + + { + const query = 'UPDATE "videoFile" SET "extname" = "extname_old"::text' + await utils.sequelize.query(query) + } + + { + const data = { + type: Sequelize.STRING, + defaultValue: null, + allowNull: false + } + await utils.queryInterface.changeColumn('videoFile', 'extname', data) + } + + { + await utils.queryInterface.removeColumn('videoFile', 'extname_old') + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From 5e755fff9d70a7fd3c4f85bb524f1b774dd85b25 Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Thu, 13 Dec 2018 09:49:45 +0100 Subject: add Content Security Policy (#1252) * add Content Security Policy * remove reflect-metadata on production builds to get rid of unsafe-eval * fix baseCSP usage * add SRI to CSP * add blob: to media-src * remove SRI * CSP set to reportOnly * adding data: to connect-src CSP * remove block-all-mixed-content * add report-uri support --- server/initializers/constants.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index ad61bee73..f1a734f48 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -290,6 +290,7 @@ const CONFIG = { get SECURITYTXT_CONTACT () { return config.get('admin.email') } }, SERVICES: { + get 'CSP-LOGGER' () { return config.get('services.csp-logger') }, TWITTER: { get USERNAME () { return config.get('services.twitter.username') }, get WHITELISTED () { return config.get('services.twitter.whitelisted') } -- cgit v1.2.3 From 9f7a19536376657e12e453f2eab656f5f95678a8 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 13 Dec 2018 16:25:15 +0100 Subject: Keep old channel/user name constraints In order to avoid compatibility issues --- server/initializers/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index f1a734f48..6971ab775 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -302,7 +302,7 @@ const CONFIG = { let CONSTRAINTS_FIELDS = { USERS: { - NAME: { min: 1, max: 50 }, // Length + NAME: { min: 1, max: 120 }, // Length DESCRIPTION: { min: 3, max: 1000 }, // Length USERNAME: { min: 1, max: 50 }, // Length PASSWORD: { min: 6, max: 255 }, // Length @@ -318,7 +318,7 @@ let CONSTRAINTS_FIELDS = { REASON: { min: 2, max: 300 } // Length }, VIDEO_CHANNELS: { - NAME: { min: 1, max: 50 }, // Length + NAME: { min: 1, max: 120 }, // Length DESCRIPTION: { min: 3, max: 1000 }, // Length SUPPORT: { min: 3, max: 1000 }, // Length URL: { min: 3, max: 2000 } // Length -- cgit v1.2.3 From 8b9a525a180cc9f3a98c334cc052dcfc8f36dcd4 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 17 Dec 2018 15:52:38 +0100 Subject: Add history on server side Add ability to disable, clear and list user videos history --- server/initializers/constants.ts | 2 +- .../migrations/0300-user-videos-history-enabled.ts | 27 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0300-user-videos-history-enabled.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 6971ab775..6e463a1d6 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 295 +const LAST_MIGRATION_VERSION = 300 // --------------------------------------------------------------------------- diff --git a/server/initializers/migrations/0300-user-videos-history-enabled.ts b/server/initializers/migrations/0300-user-videos-history-enabled.ts new file mode 100644 index 000000000..aa5fc21fb --- /dev/null +++ b/server/initializers/migrations/0300-user-videos-history-enabled.ts @@ -0,0 +1,27 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize, + db: any +}): Promise { + { + const data = { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: true + } + + await utils.queryInterface.addColumn('user', 'videosHistoryEnabled', data) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From 56b13bd193b076d32925f0ad14b755b250b803a8 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 19 Dec 2018 11:24:34 +0100 Subject: Fix federation of some videos If we don't transcode additional resolutions, and user decided to wait transcoding before publishing the video --- server/initializers/constants.ts | 2 +- .../migrations/0305-fix-unfederated-videos.ts | 52 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0305-fix-unfederated-videos.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 6e463a1d6..b326a6c7b 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 300 +const LAST_MIGRATION_VERSION = 305 // --------------------------------------------------------------------------- diff --git a/server/initializers/migrations/0305-fix-unfederated-videos.ts b/server/initializers/migrations/0305-fix-unfederated-videos.ts new file mode 100644 index 000000000..be206601f --- /dev/null +++ b/server/initializers/migrations/0305-fix-unfederated-videos.ts @@ -0,0 +1,52 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize, + db: any +}): Promise { + { + const query = `INSERT INTO "videoShare" (url, "actorId", "videoId", "createdAt", "updatedAt") ` + + `(` + + `SELECT ` + + `video.url || '/announces/' || "videoChannel"."actorId" as url, ` + + `"videoChannel"."actorId" AS "actorId", ` + + `"video"."id" AS "videoId", ` + + `NOW() AS "createdAt", ` + + `NOW() AS "updatedAt" ` + + `FROM video ` + + `INNER JOIN "videoChannel" ON "video"."channelId" = "videoChannel"."id" ` + + `WHERE "video"."remote" = false AND "video"."privacy" != 3 AND "video"."state" = 1` + + `) ` + + `ON CONFLICT DO NOTHING` + + await utils.sequelize.query(query) + } + + { + const query = `INSERT INTO "videoShare" (url, "actorId", "videoId", "createdAt", "updatedAt") ` + + `(` + + `SELECT ` + + `video.url || '/announces/' || (SELECT id FROM actor WHERE "preferredUsername" = 'peertube' ORDER BY id ASC LIMIT 1) as url, ` + + `(SELECT id FROM actor WHERE "preferredUsername" = 'peertube' ORDER BY id ASC LIMIT 1) AS "actorId", ` + + `"video"."id" AS "videoId", ` + + `NOW() AS "createdAt", ` + + `NOW() AS "updatedAt" ` + + `FROM video ` + + `WHERE "video"."remote" = false AND "video"."privacy" != 3 AND "video"."state" = 1` + + `) ` + + `ON CONFLICT DO NOTHING` + + await utils.sequelize.query(query) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From 2f5c6b2fc6e60502c2a8df4dc9029c1d87ebe30b Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 20 Dec 2018 14:31:11 +0100 Subject: Optimize actor follow scores modifications --- server/initializers/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index b326a6c7b..1c27a9f6b 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -144,7 +144,7 @@ const VIDEO_IMPORT_TIMEOUT = 1000 * 3600 // 1 hour // 1 hour let SCHEDULER_INTERVALS_MS = { - badActorFollow: 60000 * 60, // 1 hour + actorFollowScores: 60000 * 60, // 1 hour removeOldJobs: 60000 * 60, // 1 hour updateVideos: 60000, // 1 minute youtubeDLUpdate: 60000 * 60 * 24 // 1 day @@ -675,7 +675,7 @@ if (isTestInstance() === true) { CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max = 100 * 1024 // 100KB - SCHEDULER_INTERVALS_MS.badActorFollow = 10000 + SCHEDULER_INTERVALS_MS.actorFollowScores = 1000 SCHEDULER_INTERVALS_MS.removeOldJobs = 10000 SCHEDULER_INTERVALS_MS.updateVideos = 5000 REPEAT_JOBS['videos-views'] = { every: 5000 } -- cgit v1.2.3 From 439b1744f5f50b8530cded9398d51aa4bb5ed4ff Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 20 Dec 2018 15:25:24 +0100 Subject: Optimize index sizes --- server/initializers/constants.ts | 2 +- .../migrations/0310-drop-unused-video-indexes.ts | 32 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0310-drop-unused-video-indexes.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 1c27a9f6b..c3df2383a 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 305 +const LAST_MIGRATION_VERSION = 310 // --------------------------------------------------------------------------- diff --git a/server/initializers/migrations/0310-drop-unused-video-indexes.ts b/server/initializers/migrations/0310-drop-unused-video-indexes.ts new file mode 100644 index 000000000..d51f430c0 --- /dev/null +++ b/server/initializers/migrations/0310-drop-unused-video-indexes.ts @@ -0,0 +1,32 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize, + db: any +}): Promise { + const indexNames = [ + 'video_category', + 'video_licence', + 'video_nsfw', + 'video_language', + 'video_wait_transcoding', + 'video_state', + 'video_remote', + 'video_likes' + ] + + for (const indexName of indexNames) { + await utils.sequelize.query('DROP INDEX IF EXISTS "' + indexName + '";') + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From cef534ed53e4518fe0acf581bfe880788d42fc36 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 26 Dec 2018 10:36:24 +0100 Subject: Add user notification base code --- server/initializers/constants.ts | 4 +++- server/initializers/database.ts | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index c3df2383a..fcfaf71a0 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -50,7 +50,9 @@ const SORTABLE_COLUMNS = { VIDEO_CHANNELS_SEARCH: [ 'match', 'displayName', 'createdAt' ], ACCOUNTS_BLOCKLIST: [ 'createdAt' ], - SERVERS_BLOCKLIST: [ 'createdAt' ] + SERVERS_BLOCKLIST: [ 'createdAt' ], + + USER_NOTIFICATIONS: [ 'createdAt' ] } const OAUTH_LIFETIME = { diff --git a/server/initializers/database.ts b/server/initializers/database.ts index 40cd659ab..84ad2079b 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts @@ -31,6 +31,8 @@ import { VideoRedundancyModel } from '../models/redundancy/video-redundancy' import { UserVideoHistoryModel } from '../models/account/user-video-history' import { AccountBlocklistModel } from '../models/account/account-blocklist' import { ServerBlocklistModel } from '../models/server/server-blocklist' +import { UserNotificationModel } from '../models/account/user-notification' +import { UserNotificationSettingModel } from '../models/account/user-notification-setting' require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string @@ -95,7 +97,9 @@ async function initDatabaseModels (silent: boolean) { VideoRedundancyModel, UserVideoHistoryModel, AccountBlocklistModel, - ServerBlocklistModel + ServerBlocklistModel, + UserNotificationModel, + UserNotificationSettingModel ]) // Check extensions exist in the database -- cgit v1.2.3 From e8d246d5267ea8b6b3114d4bcf4f34fe5f3a5241 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 28 Dec 2018 13:47:17 +0100 Subject: Add notification settings migration --- server/initializers/constants.ts | 2 +- .../migrations/0315-user-notifications.ts | 41 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0315-user-notifications.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index fcfaf71a0..91e74f6c7 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 310 +const LAST_MIGRATION_VERSION = 315 // --------------------------------------------------------------------------- diff --git a/server/initializers/migrations/0315-user-notifications.ts b/server/initializers/migrations/0315-user-notifications.ts new file mode 100644 index 000000000..2bd9c657d --- /dev/null +++ b/server/initializers/migrations/0315-user-notifications.ts @@ -0,0 +1,41 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize +}): Promise { + + { + const query = ` +CREATE TABLE IF NOT EXISTS "userNotificationSetting" ("id" SERIAL, +"newVideoFromSubscription" INTEGER NOT NULL DEFAULT NULL, +"newCommentOnMyVideo" INTEGER NOT NULL DEFAULT NULL, +"videoAbuseAsModerator" INTEGER NOT NULL DEFAULT NULL, +"blacklistOnMyVideo" INTEGER NOT NULL DEFAULT NULL, +"userId" INTEGER REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE, +"createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, +"updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, +PRIMARY KEY ("id")) +` + await utils.sequelize.query(query) + } + + { + const query = 'INSERT INTO "userNotificationSetting" ' + + '("newVideoFromSubscription", "newCommentOnMyVideo", "videoAbuseAsModerator", "blacklistOnMyVideo", ' + + '"userId", "createdAt", "updatedAt") ' + + '(SELECT 2, 2, 4, 4, id, NOW(), NOW() FROM "user")' + + await utils.sequelize.query(query) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From dc13348070d808d0ba3feb56a435b835c2e7e791 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 2 Jan 2019 16:37:43 +0100 Subject: Add import finished and video published notifs --- server/initializers/migrations/0315-user-notifications.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/migrations/0315-user-notifications.ts b/server/initializers/migrations/0315-user-notifications.ts index 2bd9c657d..8c54c5d6c 100644 --- a/server/initializers/migrations/0315-user-notifications.ts +++ b/server/initializers/migrations/0315-user-notifications.ts @@ -13,6 +13,8 @@ CREATE TABLE IF NOT EXISTS "userNotificationSetting" ("id" SERIAL, "newCommentOnMyVideo" INTEGER NOT NULL DEFAULT NULL, "videoAbuseAsModerator" INTEGER NOT NULL DEFAULT NULL, "blacklistOnMyVideo" INTEGER NOT NULL DEFAULT NULL, +"myVideoPublished" INTEGER NOT NULL DEFAULT NULL, +"myVideoImportFinished" INTEGER NOT NULL DEFAULT NULL, "userId" INTEGER REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, @@ -24,8 +26,8 @@ PRIMARY KEY ("id")) { const query = 'INSERT INTO "userNotificationSetting" ' + '("newVideoFromSubscription", "newCommentOnMyVideo", "videoAbuseAsModerator", "blacklistOnMyVideo", ' + - '"userId", "createdAt", "updatedAt") ' + - '(SELECT 2, 2, 4, 4, id, NOW(), NOW() FROM "user")' + '"myVideoPublished", "myVideoImportFinished", "userId", "createdAt", "updatedAt") ' + + '(SELECT 2, 2, 4, 4, 2, 2, id, NOW(), NOW() FROM "user")' await utils.sequelize.query(query) } -- cgit v1.2.3 From f7cc67b455a12ccae9b0ea16876d166720364357 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 4 Jan 2019 08:56:20 +0100 Subject: Add new follow, mention and user registered notifs --- server/initializers/migrations/0315-user-notifications.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/migrations/0315-user-notifications.ts b/server/initializers/migrations/0315-user-notifications.ts index 8c54c5d6c..34f9fd193 100644 --- a/server/initializers/migrations/0315-user-notifications.ts +++ b/server/initializers/migrations/0315-user-notifications.ts @@ -15,6 +15,9 @@ CREATE TABLE IF NOT EXISTS "userNotificationSetting" ("id" SERIAL, "blacklistOnMyVideo" INTEGER NOT NULL DEFAULT NULL, "myVideoPublished" INTEGER NOT NULL DEFAULT NULL, "myVideoImportFinished" INTEGER NOT NULL DEFAULT NULL, +"newUserRegistration" INTEGER NOT NULL DEFAULT NULL, +"newFollow" INTEGER NOT NULL DEFAULT NULL, +"commentMention" INTEGER NOT NULL DEFAULT NULL, "userId" INTEGER REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, @@ -26,8 +29,9 @@ PRIMARY KEY ("id")) { const query = 'INSERT INTO "userNotificationSetting" ' + '("newVideoFromSubscription", "newCommentOnMyVideo", "videoAbuseAsModerator", "blacklistOnMyVideo", ' + - '"myVideoPublished", "myVideoImportFinished", "userId", "createdAt", "updatedAt") ' + - '(SELECT 2, 2, 4, 4, 2, 2, id, NOW(), NOW() FROM "user")' + '"myVideoPublished", "myVideoImportFinished", "newUserRegistration", "newFollow", "commentMention", ' + + '"userId", "createdAt", "updatedAt") ' + + '(SELECT 2, 2, 4, 4, 2, 2, 2, 2, 2, id, NOW(), NOW() FROM "user")' await utils.sequelize.query(query) } -- cgit v1.2.3 From 2f1548fda32c3ba9e53913270394eedfacd55986 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 8 Jan 2019 11:26:41 +0100 Subject: Add notifications in the client --- server/initializers/migrations/0315-user-notifications.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/initializers') diff --git a/server/initializers/migrations/0315-user-notifications.ts b/server/initializers/migrations/0315-user-notifications.ts index 34f9fd193..8284c58a0 100644 --- a/server/initializers/migrations/0315-user-notifications.ts +++ b/server/initializers/migrations/0315-user-notifications.ts @@ -31,7 +31,7 @@ PRIMARY KEY ("id")) '("newVideoFromSubscription", "newCommentOnMyVideo", "videoAbuseAsModerator", "blacklistOnMyVideo", ' + '"myVideoPublished", "myVideoImportFinished", "newUserRegistration", "newFollow", "commentMention", ' + '"userId", "createdAt", "updatedAt") ' + - '(SELECT 2, 2, 4, 4, 2, 2, 2, 2, 2, id, NOW(), NOW() FROM "user")' + '(SELECT 1, 1, 3, 3, 1, 1, 1, 1, 1, id, NOW(), NOW() FROM "user")' await utils.sequelize.query(query) } -- cgit v1.2.3 From a4101923e699e49ceb9ff36e971c75417fafc9f0 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 9 Jan 2019 15:14:29 +0100 Subject: Implement contact form on server side --- server/initializers/constants.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 91e74f6c7..4a88aef87 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -231,6 +231,9 @@ const CONFIG = { ADMIN: { get EMAIL () { return config.get('admin.email') } }, + CONTACT_FORM: { + get ENABLED () { return config.get('contact_form.enabled') } + }, SIGNUP: { get ENABLED () { return config.get('signup.enabled') }, get LIMIT () { return config.get('signup.limit') }, @@ -394,6 +397,10 @@ let CONSTRAINTS_FIELDS = { }, VIDEO_SHARE: { URL: { min: 3, max: 2000 } // Length + }, + CONTACT_FORM: { + FROM_NAME: { min: 1, max: 120 }, // Length + BODY: { min: 3, max: 5000 } // Length } } @@ -409,6 +416,8 @@ const RATES_LIMIT = { } let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour +let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour + const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = { MIN: 10, AVERAGE: 30, @@ -685,6 +694,7 @@ if (isTestInstance() === true) { REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1 VIDEO_VIEW_LIFETIME = 1000 // 1 second + CONTACT_FORM_LIFETIME = 1000 // 1 second JOB_ATTEMPTS['email'] = 1 @@ -756,6 +766,7 @@ export { HTTP_SIGNATURE, VIDEO_IMPORT_STATES, VIDEO_VIEW_LIFETIME, + CONTACT_FORM_LIFETIME, buildLanguages } -- cgit v1.2.3 From d3e56c0c4b307c99e83fbafb7f2c5884cbc20055 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 10 Jan 2019 11:12:41 +0100 Subject: Implement contact form in the client --- server/initializers/checker-after-init.ts | 14 +++++++++++++- server/initializers/checker-before-init.ts | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'server/initializers') diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts index 72d846957..955d55206 100644 --- a/server/initializers/checker-after-init.ts +++ b/server/initializers/checker-after-init.ts @@ -10,6 +10,7 @@ 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' async function checkActivityPubUrls () { const actor = await getServerActor() @@ -32,9 +33,19 @@ async function checkActivityPubUrls () { // Some checks on configuration files // Return an error message, or null if everything is okay function checkConfig () { - const defaultNSFWPolicy = CONFIG.INSTANCE.DEFAULT_NSFW_POLICY + + if (!Emailer.isEnabled()) { + if (CONFIG.SIGNUP.ENABLED && CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) { + return 'Emailer is disabled but you require signup email verification.' + } + + if (CONFIG.CONTACT_FORM.ENABLED) { + logger.warn('Emailer is disabled so the contact form will not work.') + } + } // NSFW policy + const defaultNSFWPolicy = CONFIG.INSTANCE.DEFAULT_NSFW_POLICY { const available = [ 'do_not_list', 'blur', 'display' ] if (available.indexOf(defaultNSFWPolicy) === -1) { @@ -68,6 +79,7 @@ function checkConfig () { } } + // Check storage directory locations if (isProdInstance()) { const configStorage = config.get('storage') for (const key of Object.keys(configStorage)) { diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index a7bc7eec8..7905d9ffa 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts @@ -15,7 +15,7 @@ function checkMissedConfig () { 'storage.redundancy', 'storage.tmp', 'log.level', 'user.video_quota', 'user.video_quota_daily', - 'cache.previews.size', 'admin.email', + 'cache.previews.size', 'admin.email', 'contact_form.enabled', 'signup.enabled', 'signup.limit', 'signup.requires_email_verification', 'signup.filters.cidr.whitelist', 'signup.filters.cidr.blacklist', 'redundancy.videos.strategies', 'redundancy.videos.check_interval', -- cgit v1.2.3 From 5abb9fbbd12e7097e348d6a38622d364b1fa47ed Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 10 Jan 2019 15:39:51 +0100 Subject: Add ability to unfederate a local video (on blacklist) --- server/initializers/constants.ts | 2 +- .../migrations/0320-blacklist-unfederate.ts | 27 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0320-blacklist-unfederate.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 4a88aef87..b18884eeb 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 315 +const LAST_MIGRATION_VERSION = 320 // --------------------------------------------------------------------------- diff --git a/server/initializers/migrations/0320-blacklist-unfederate.ts b/server/initializers/migrations/0320-blacklist-unfederate.ts new file mode 100644 index 000000000..6fb7bbb90 --- /dev/null +++ b/server/initializers/migrations/0320-blacklist-unfederate.ts @@ -0,0 +1,27 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize +}): Promise { + + { + const data = { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false + } + + await utils.queryInterface.addColumn('videoBlacklist', 'unfederated', data) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From 1506307f2f903ce0f80155072a33345c702b7c76 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 14 Jan 2019 16:48:38 +0100 Subject: Increase abuse length to 3000 And correctly handle new lines --- server/initializers/constants.ts | 6 ++-- .../migrations/0325-video-abuse-fields.ts | 37 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 server/initializers/migrations/0325-video-abuse-fields.ts (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index b18884eeb..93fdd3f03 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 320 +const LAST_MIGRATION_VERSION = 325 // --------------------------------------------------------------------------- @@ -316,8 +316,8 @@ let CONSTRAINTS_FIELDS = { BLOCKED_REASON: { min: 3, max: 250 } // Length }, VIDEO_ABUSES: { - REASON: { min: 2, max: 300 }, // Length - MODERATION_COMMENT: { min: 2, max: 300 } // Length + REASON: { min: 2, max: 3000 }, // Length + MODERATION_COMMENT: { min: 2, max: 3000 } // Length }, VIDEO_BLACKLIST: { REASON: { min: 2, max: 300 } // Length diff --git a/server/initializers/migrations/0325-video-abuse-fields.ts b/server/initializers/migrations/0325-video-abuse-fields.ts new file mode 100644 index 000000000..fca6d666f --- /dev/null +++ b/server/initializers/migrations/0325-video-abuse-fields.ts @@ -0,0 +1,37 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize +}): Promise { + + { + const data = { + type: Sequelize.STRING(3000), + allowNull: false, + defaultValue: null + } + + await utils.queryInterface.changeColumn('videoAbuse', 'reason', data) + } + + { + const data = { + type: Sequelize.STRING(3000), + allowNull: true, + defaultValue: null + } + + await utils.queryInterface.changeColumn('videoAbuse', 'moderationComment', data) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From ebff55d8d6747d0627f135ab668f43e0d6125a37 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 21 Jan 2019 15:58:07 +0100 Subject: Fix tests --- server/initializers/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 93fdd3f03..dab986353 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -149,7 +149,7 @@ let SCHEDULER_INTERVALS_MS = { actorFollowScores: 60000 * 60, // 1 hour removeOldJobs: 60000 * 60, // 1 hour updateVideos: 60000, // 1 minute - youtubeDLUpdate: 60000 * 60 * 24 // 1 day + youtubeDLUpdate: 60000 // 1 day } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 0c5892764e74f4a614f0087028e0687694b176d3 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 21 Jan 2019 16:22:15 +0100 Subject: Youtube DL update every 24 hours --- server/initializers/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index dab986353..93fdd3f03 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -149,7 +149,7 @@ let SCHEDULER_INTERVALS_MS = { actorFollowScores: 60000 * 60, // 1 hour removeOldJobs: 60000 * 60, // 1 hour updateVideos: 60000, // 1 minute - youtubeDLUpdate: 60000 // 1 day + youtubeDLUpdate: 60000 * 60 * 24 // 1 day } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 307902e2b3248073aeb677e420aafd8b5e041117 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 24 Jan 2019 15:23:06 +0100 Subject: Try to fix Mac video upload --- server/initializers/constants.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 93fdd3f03..6f3ebb9aa 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -795,7 +795,9 @@ function buildVideoMimetypeExt () { 'video/quicktime': '.mov', 'video/x-msvideo': '.avi', 'video/x-flv': '.flv', - 'video/x-matroska': '.mkv' + 'video/x-matroska': '.mkv', + 'application/octet-stream': '.mkv', + 'video/avi': '.avi' }) } -- cgit v1.2.3 From 092092969633bbcf6d4891a083ea497a7d5c3154 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 29 Jan 2019 08:37:25 +0100 Subject: Add hls support on server --- server/initializers/checker-before-init.ts | 2 +- server/initializers/constants.ts | 14 +++++- server/initializers/database.ts | 4 +- server/initializers/installer.ts | 5 ++- .../migrations/0330-video-streaming-playlist.ts | 51 ++++++++++++++++++++++ 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 server/initializers/migrations/0330-video-streaming-playlist.ts (limited to 'server/initializers') diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index 7905d9ffa..29fdb263e 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts @@ -12,7 +12,7 @@ function checkMissedConfig () { 'database.hostname', 'database.port', 'database.suffix', 'database.username', 'database.password', 'database.pool.max', 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address', 'storage.avatars', 'storage.videos', 'storage.logs', 'storage.previews', 'storage.thumbnails', 'storage.torrents', 'storage.cache', - 'storage.redundancy', 'storage.tmp', + 'storage.redundancy', 'storage.tmp', 'storage.playlists', 'log.level', 'user.video_quota', 'user.video_quota_daily', 'cache.previews.size', 'admin.email', 'contact_form.enabled', diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 6f3ebb9aa..98f8f8694 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -16,7 +16,7 @@ let config: IConfig = require('config') // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 325 +const LAST_MIGRATION_VERSION = 330 // --------------------------------------------------------------------------- @@ -192,6 +192,7 @@ const CONFIG = { AVATARS_DIR: buildPath(config.get('storage.avatars')), LOG_DIR: buildPath(config.get('storage.logs')), VIDEOS_DIR: buildPath(config.get('storage.videos')), + PLAYLISTS_DIR: buildPath(config.get('storage.playlists')), REDUNDANCY_DIR: buildPath(config.get('storage.redundancy')), THUMBNAILS_DIR: buildPath(config.get('storage.thumbnails')), PREVIEWS_DIR: buildPath(config.get('storage.previews')), @@ -259,6 +260,9 @@ const CONFIG = { get '480p' () { return config.get('transcoding.resolutions.480p') }, get '720p' () { return config.get('transcoding.resolutions.720p') }, get '1080p' () { return config.get('transcoding.resolutions.1080p') } + }, + HLS: { + get ENABLED () { return config.get('transcoding.hls.enabled') } } }, IMPORT: { @@ -590,6 +594,9 @@ const STATIC_PATHS = { TORRENTS: '/static/torrents/', WEBSEED: '/static/webseed/', REDUNDANCY: '/static/redundancy/', + PLAYLISTS: { + HLS: '/static/playlists/hls' + }, AVATARS: '/static/avatars/', VIDEO_CAPTIONS: '/static/video-captions/' } @@ -632,6 +639,9 @@ const CACHE = { } } +const HLS_PLAYLIST_DIRECTORY = join(CONFIG.STORAGE.PLAYLISTS_DIR, 'hls') +const HLS_REDUNDANCY_DIRECTORY = join(CONFIG.STORAGE.REDUNDANCY_DIR, 'hls') + const MEMOIZE_TTL = { OVERVIEWS_SAMPLE: 1000 * 3600 * 4 // 4 hours } @@ -709,6 +719,7 @@ updateWebserverUrls() export { API_VERSION, + HLS_REDUNDANCY_DIRECTORY, AVATARS_SIZE, ACCEPT_HEADERS, BCRYPT_SALT_SIZE, @@ -733,6 +744,7 @@ export { PRIVATE_RSA_KEY_SIZE, ROUTE_CACHE_LIFETIME, SORTABLE_COLUMNS, + HLS_PLAYLIST_DIRECTORY, FEEDS, JOB_TTL, NSFW_POLICY_TYPES, diff --git a/server/initializers/database.ts b/server/initializers/database.ts index 84ad2079b..fe296142d 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts @@ -33,6 +33,7 @@ import { AccountBlocklistModel } from '../models/account/account-blocklist' import { ServerBlocklistModel } from '../models/server/server-blocklist' import { UserNotificationModel } from '../models/account/user-notification' import { UserNotificationSettingModel } from '../models/account/user-notification-setting' +import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist' require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string @@ -99,7 +100,8 @@ async function initDatabaseModels (silent: boolean) { AccountBlocklistModel, ServerBlocklistModel, UserNotificationModel, - UserNotificationSettingModel + UserNotificationSettingModel, + VideoStreamingPlaylistModel ]) // Check extensions exist in the database diff --git a/server/initializers/installer.ts b/server/initializers/installer.ts index b9a9da183..2b22e16fe 100644 --- a/server/initializers/installer.ts +++ b/server/initializers/installer.ts @@ -6,7 +6,7 @@ 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 { CACHE, CONFIG, LAST_MIGRATION_VERSION } from './constants' +import { CACHE, CONFIG, HLS_PLAYLIST_DIRECTORY, LAST_MIGRATION_VERSION } from './constants' import { sequelizeTypescript } from './database' import { remove, ensureDir } from 'fs-extra' @@ -73,6 +73,9 @@ function createDirectoriesIfNotExist () { tasks.push(ensureDir(dir)) } + // Playlist directories + tasks.push(ensureDir(HLS_PLAYLIST_DIRECTORY)) + return Promise.all(tasks) } diff --git a/server/initializers/migrations/0330-video-streaming-playlist.ts b/server/initializers/migrations/0330-video-streaming-playlist.ts new file mode 100644 index 000000000..c85a762ab --- /dev/null +++ b/server/initializers/migrations/0330-video-streaming-playlist.ts @@ -0,0 +1,51 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize +}): Promise { + + { + const query = ` + CREATE TABLE IF NOT EXISTS "videoStreamingPlaylist" +( + "id" SERIAL, + "type" INTEGER NOT NULL, + "playlistUrl" VARCHAR(2000) NOT NULL, + "p2pMediaLoaderInfohashes" VARCHAR(255)[] NOT NULL, + "segmentsSha256Url" VARCHAR(255) NOT NULL, + "videoId" INTEGER NOT NULL REFERENCES "video" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, + "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, + PRIMARY KEY ("id") +);` + await utils.sequelize.query(query) + } + + { + const data = { + type: Sequelize.INTEGER, + allowNull: true, + defaultValue: null + } + + await utils.queryInterface.changeColumn('videoRedundancy', 'videoFileId', data) + } + + { + const query = 'ALTER TABLE "videoRedundancy" ADD COLUMN "videoStreamingPlaylistId" INTEGER NULL ' + + 'REFERENCES "videoStreamingPlaylist" ("id") ON DELETE CASCADE ON UPDATE CASCADE' + + await utils.sequelize.query(query) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} -- cgit v1.2.3 From b426edd4854adc6e65844d8c54b8998e792b5778 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 11 Feb 2019 09:30:29 +0100 Subject: Cleanup reset user password by admin And add some tests --- server/initializers/constants.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'server/initializers') diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 98f8f8694..e5c4c4e63 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -711,6 +711,8 @@ if (isTestInstance() === true) { CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1 ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms' + + RATES_LIMIT.LOGIN.MAX = 20 } updateWebserverUrls() -- cgit v1.2.3