aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-04-09 14:51:28 +0200
committerChocobozzz <me@florianbigard.com>2021-04-09 15:17:43 +0200
commit22820226e54dee61287666a178df2176fafb202a (patch)
tree3fce30315da83eda4b4f96064ad2703202d0d0f5 /server
parent023edc8a54a58d15f8d4f00d7f76e0074d0d3a81 (diff)
downloadPeerTube-22820226e54dee61287666a178df2176fafb202a.tar.gz
PeerTube-22820226e54dee61287666a178df2176fafb202a.tar.zst
PeerTube-22820226e54dee61287666a178df2176fafb202a.zip
Add server plugin helpers
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/config.ts250
-rw-r--r--server/controllers/static.ts2
-rw-r--r--server/helpers/signup.ts2
-rw-r--r--server/lib/config.ts255
-rw-r--r--server/lib/plugins/plugin-helpers-builder.ts17
-rw-r--r--server/lib/plugins/register-helpers.ts2
-rw-r--r--server/tests/fixtures/peertube-plugin-test-four/main.js13
-rw-r--r--server/tests/plugins/plugin-helpers.ts27
-rw-r--r--server/types/plugins/register-server-option.model.ts7
9 files changed, 326 insertions, 249 deletions
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
index e28f7502d..2ddb73519 100644
--- a/server/controllers/api/config.ts
+++ b/server/controllers/api/config.ts
@@ -1,24 +1,17 @@
1import { Hooks } from '@server/lib/plugins/hooks'
2import * as express from 'express' 1import * as express from 'express'
3import { remove, writeJSON } from 'fs-extra' 2import { remove, writeJSON } from 'fs-extra'
4import { snakeCase } from 'lodash' 3import { snakeCase } from 'lodash'
5import validator from 'validator' 4import validator from 'validator'
6import { RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig, UserRight } from '../../../shared' 5import { getServerConfig } from '@server/lib/config'
6import { UserRight } from '../../../shared'
7import { About } from '../../../shared/models/server/about.model' 7import { About } from '../../../shared/models/server/about.model'
8import { CustomConfig } from '../../../shared/models/server/custom-config.model' 8import { CustomConfig } from '../../../shared/models/server/custom-config.model'
9import { auditLoggerFactory, CustomConfigAuditView, getAuditIdFromRes } from '../../helpers/audit-logger' 9import { auditLoggerFactory, CustomConfigAuditView, getAuditIdFromRes } from '../../helpers/audit-logger'
10import { objectConverter } from '../../helpers/core-utils' 10import { objectConverter } from '../../helpers/core-utils'
11import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/signup' 11import { CONFIG, reloadConfig } from '../../initializers/config'
12import { getServerCommit } from '../../helpers/utils'
13import { getEnabledResolutions } from '../../lib/video-transcoding'
14import { CONFIG, isEmailEnabled, reloadConfig } from '../../initializers/config'
15import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '../../initializers/constants'
16import { ClientHtml } from '../../lib/client-html' 12import { ClientHtml } from '../../lib/client-html'
17import { PluginManager } from '../../lib/plugins/plugin-manager'
18import { getThemeOrDefault } from '../../lib/plugins/theme-utils'
19import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../middlewares' 13import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../middlewares'
20import { customConfigUpdateValidator } from '../../middlewares/validators/config' 14import { customConfigUpdateValidator } from '../../middlewares/validators/config'
21import { VideoTranscodingProfilesManager } from '@server/lib/video-transcoding-profiles'
22 15
23const configRouter = express.Router() 16const configRouter = express.Router()
24 17
@@ -46,182 +39,8 @@ configRouter.delete('/custom',
46 asyncMiddleware(deleteCustomConfig) 39 asyncMiddleware(deleteCustomConfig)
47) 40)
48 41
49let serverCommit: string
50
51async function getConfig (req: express.Request, res: express.Response) { 42async function getConfig (req: express.Request, res: express.Response) {
52 const { allowed } = await Hooks.wrapPromiseFun( 43 const json = await getServerConfig(req.ip)
53 isSignupAllowed,
54 {
55 ip: req.ip
56 },
57 'filter:api.user.signup.allowed.result'
58 )
59
60 const allowedForCurrentIP = isSignupAllowedForCurrentIP(req.ip)
61 const defaultTheme = getThemeOrDefault(CONFIG.THEME.DEFAULT, DEFAULT_THEME_NAME)
62
63 if (serverCommit === undefined) serverCommit = await getServerCommit()
64
65 const json: ServerConfig = {
66 instance: {
67 name: CONFIG.INSTANCE.NAME,
68 shortDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION,
69 isNSFW: CONFIG.INSTANCE.IS_NSFW,
70 defaultNSFWPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
71 defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE,
72 customizations: {
73 javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT,
74 css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS
75 }
76 },
77 search: {
78 remoteUri: {
79 users: CONFIG.SEARCH.REMOTE_URI.USERS,
80 anonymous: CONFIG.SEARCH.REMOTE_URI.ANONYMOUS
81 },
82 searchIndex: {
83 enabled: CONFIG.SEARCH.SEARCH_INDEX.ENABLED,
84 url: CONFIG.SEARCH.SEARCH_INDEX.URL,
85 disableLocalSearch: CONFIG.SEARCH.SEARCH_INDEX.DISABLE_LOCAL_SEARCH,
86 isDefaultSearch: CONFIG.SEARCH.SEARCH_INDEX.IS_DEFAULT_SEARCH
87 }
88 },
89 plugin: {
90 registered: getRegisteredPlugins(),
91 registeredExternalAuths: getExternalAuthsPlugins(),
92 registeredIdAndPassAuths: getIdAndPassAuthPlugins()
93 },
94 theme: {
95 registered: getRegisteredThemes(),
96 default: defaultTheme
97 },
98 email: {
99 enabled: isEmailEnabled()
100 },
101 contactForm: {
102 enabled: CONFIG.CONTACT_FORM.ENABLED
103 },
104 serverVersion: PEERTUBE_VERSION,
105 serverCommit,
106 signup: {
107 allowed,
108 allowedForCurrentIP,
109 requiresEmailVerification: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION
110 },
111 transcoding: {
112 hls: {
113 enabled: CONFIG.TRANSCODING.HLS.ENABLED
114 },
115 webtorrent: {
116 enabled: CONFIG.TRANSCODING.WEBTORRENT.ENABLED
117 },
118 enabledResolutions: getEnabledResolutions('vod'),
119 profile: CONFIG.TRANSCODING.PROFILE,
120 availableProfiles: VideoTranscodingProfilesManager.Instance.getAvailableProfiles('vod')
121 },
122 live: {
123 enabled: CONFIG.LIVE.ENABLED,
124
125 allowReplay: CONFIG.LIVE.ALLOW_REPLAY,
126 maxDuration: CONFIG.LIVE.MAX_DURATION,
127 maxInstanceLives: CONFIG.LIVE.MAX_INSTANCE_LIVES,
128 maxUserLives: CONFIG.LIVE.MAX_USER_LIVES,
129
130 transcoding: {
131 enabled: CONFIG.LIVE.TRANSCODING.ENABLED,
132 enabledResolutions: getEnabledResolutions('live'),
133 profile: CONFIG.LIVE.TRANSCODING.PROFILE,
134 availableProfiles: VideoTranscodingProfilesManager.Instance.getAvailableProfiles('live')
135 },
136
137 rtmp: {
138 port: CONFIG.LIVE.RTMP.PORT
139 }
140 },
141 import: {
142 videos: {
143 http: {
144 enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED
145 },
146 torrent: {
147 enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED
148 }
149 }
150 },
151 autoBlacklist: {
152 videos: {
153 ofUsers: {
154 enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED
155 }
156 }
157 },
158 avatar: {
159 file: {
160 size: {
161 max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max
162 },
163 extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME
164 }
165 },
166 banner: {
167 file: {
168 size: {
169 max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max
170 },
171 extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME
172 }
173 },
174 video: {
175 image: {
176 extensions: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME,
177 size: {
178 max: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max
179 }
180 },
181 file: {
182 extensions: CONSTRAINTS_FIELDS.VIDEOS.EXTNAME
183 }
184 },
185 videoCaption: {
186 file: {
187 size: {
188 max: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.FILE_SIZE.max
189 },
190 extensions: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.EXTNAME
191 }
192 },
193 user: {
194 videoQuota: CONFIG.USER.VIDEO_QUOTA,
195 videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY
196 },
197 trending: {
198 videos: {
199 intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS,
200 algorithms: {
201 enabled: CONFIG.TRENDING.VIDEOS.ALGORITHMS.ENABLED,
202 default: CONFIG.TRENDING.VIDEOS.ALGORITHMS.DEFAULT
203 }
204 }
205 },
206 tracker: {
207 enabled: CONFIG.TRACKER.ENABLED
208 },
209
210 followings: {
211 instance: {
212 autoFollowIndex: {
213 indexUrl: CONFIG.FOLLOWINGS.INSTANCE.AUTO_FOLLOW_INDEX.INDEX_URL
214 }
215 }
216 },
217
218 broadcastMessage: {
219 enabled: CONFIG.BROADCAST_MESSAGE.ENABLED,
220 message: CONFIG.BROADCAST_MESSAGE.MESSAGE,
221 level: CONFIG.BROADCAST_MESSAGE.LEVEL,
222 dismissable: CONFIG.BROADCAST_MESSAGE.DISMISSABLE
223 }
224 }
225 44
226 return res.json(json) 45 return res.json(json)
227} 46}
@@ -292,69 +111,10 @@ async function updateCustomConfig (req: express.Request, res: express.Response)
292 return res.json(data) 111 return res.json(data)
293} 112}
294 113
295function getRegisteredThemes () {
296 return PluginManager.Instance.getRegisteredThemes()
297 .map(t => ({
298 name: t.name,
299 version: t.version,
300 description: t.description,
301 css: t.css,
302 clientScripts: t.clientScripts
303 }))
304}
305
306function getRegisteredPlugins () {
307 return PluginManager.Instance.getRegisteredPlugins()
308 .map(p => ({
309 name: p.name,
310 version: p.version,
311 description: p.description,
312 clientScripts: p.clientScripts
313 }))
314}
315
316function getIdAndPassAuthPlugins () {
317 const result: RegisteredIdAndPassAuthConfig[] = []
318
319 for (const p of PluginManager.Instance.getIdAndPassAuths()) {
320 for (const auth of p.idAndPassAuths) {
321 result.push({
322 npmName: p.npmName,
323 name: p.name,
324 version: p.version,
325 authName: auth.authName,
326 weight: auth.getWeight()
327 })
328 }
329 }
330
331 return result
332}
333
334function getExternalAuthsPlugins () {
335 const result: RegisteredExternalAuthConfig[] = []
336
337 for (const p of PluginManager.Instance.getExternalAuths()) {
338 for (const auth of p.externalAuths) {
339 result.push({
340 npmName: p.npmName,
341 name: p.name,
342 version: p.version,
343 authName: auth.authName,
344 authDisplayName: auth.authDisplayName()
345 })
346 }
347 }
348
349 return result
350}
351
352// --------------------------------------------------------------------------- 114// ---------------------------------------------------------------------------
353 115
354export { 116export {
355 configRouter, 117 configRouter
356 getRegisteredPlugins,
357 getRegisteredThemes
358} 118}
359 119
360// --------------------------------------------------------------------------- 120// ---------------------------------------------------------------------------
diff --git a/server/controllers/static.ts b/server/controllers/static.ts
index e6a0628e6..8d9003a3e 100644
--- a/server/controllers/static.ts
+++ b/server/controllers/static.ts
@@ -1,8 +1,8 @@
1import * as cors from 'cors' 1import * as cors from 'cors'
2import * as express from 'express' 2import * as express from 'express'
3import { join } from 'path' 3import { join } from 'path'
4import { getRegisteredPlugins, getRegisteredThemes } from '@server/controllers/api/config'
5import { serveIndexHTML } from '@server/lib/client-html' 4import { serveIndexHTML } from '@server/lib/client-html'
5import { getRegisteredPlugins, getRegisteredThemes } from '@server/lib/config'
6import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' 6import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
7import { HttpNodeinfoDiasporaSoftwareNsSchema20 } from '../../shared/models/nodeinfo' 7import { HttpNodeinfoDiasporaSoftwareNsSchema20 } from '../../shared/models/nodeinfo'
8import { root } from '../helpers/core-utils' 8import { root } from '../helpers/core-utils'
diff --git a/server/helpers/signup.ts b/server/helpers/signup.ts
index d34ff2db5..ed872539b 100644
--- a/server/helpers/signup.ts
+++ b/server/helpers/signup.ts
@@ -20,6 +20,8 @@ async function isSignupAllowed (): Promise<{ allowed: boolean, errorMessage?: st
20} 20}
21 21
22function isSignupAllowedForCurrentIP (ip: string) { 22function isSignupAllowedForCurrentIP (ip: string) {
23 if (!ip) return false
24
23 const addr = ipaddr.parse(ip) 25 const addr = ipaddr.parse(ip)
24 const excludeList = [ 'blacklist' ] 26 const excludeList = [ 'blacklist' ]
25 let matched = '' 27 let matched = ''
diff --git a/server/lib/config.ts b/server/lib/config.ts
new file mode 100644
index 000000000..b4c4c9299
--- /dev/null
+++ b/server/lib/config.ts
@@ -0,0 +1,255 @@
1import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/helpers/signup'
2import { getServerCommit } from '@server/helpers/utils'
3import { CONFIG, isEmailEnabled } from '@server/initializers/config'
4import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants'
5import { RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models'
6import { Hooks } from './plugins/hooks'
7import { PluginManager } from './plugins/plugin-manager'
8import { getThemeOrDefault } from './plugins/theme-utils'
9import { getEnabledResolutions } from './video-transcoding'
10import { VideoTranscodingProfilesManager } from './video-transcoding-profiles'
11
12let serverCommit: string
13
14async function getServerConfig (ip?: string): Promise<ServerConfig> {
15 if (serverCommit === undefined) serverCommit = await getServerCommit()
16
17 const { allowed } = await Hooks.wrapPromiseFun(
18 isSignupAllowed,
19 {
20 ip
21 },
22 'filter:api.user.signup.allowed.result'
23 )
24
25 const allowedForCurrentIP = isSignupAllowedForCurrentIP(ip)
26 const defaultTheme = getThemeOrDefault(CONFIG.THEME.DEFAULT, DEFAULT_THEME_NAME)
27
28 return {
29 instance: {
30 name: CONFIG.INSTANCE.NAME,
31 shortDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION,
32 isNSFW: CONFIG.INSTANCE.IS_NSFW,
33 defaultNSFWPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
34 defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE,
35 customizations: {
36 javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT,
37 css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS
38 }
39 },
40 search: {
41 remoteUri: {
42 users: CONFIG.SEARCH.REMOTE_URI.USERS,
43 anonymous: CONFIG.SEARCH.REMOTE_URI.ANONYMOUS
44 },
45 searchIndex: {
46 enabled: CONFIG.SEARCH.SEARCH_INDEX.ENABLED,
47 url: CONFIG.SEARCH.SEARCH_INDEX.URL,
48 disableLocalSearch: CONFIG.SEARCH.SEARCH_INDEX.DISABLE_LOCAL_SEARCH,
49 isDefaultSearch: CONFIG.SEARCH.SEARCH_INDEX.IS_DEFAULT_SEARCH
50 }
51 },
52 plugin: {
53 registered: getRegisteredPlugins(),
54 registeredExternalAuths: getExternalAuthsPlugins(),
55 registeredIdAndPassAuths: getIdAndPassAuthPlugins()
56 },
57 theme: {
58 registered: getRegisteredThemes(),
59 default: defaultTheme
60 },
61 email: {
62 enabled: isEmailEnabled()
63 },
64 contactForm: {
65 enabled: CONFIG.CONTACT_FORM.ENABLED
66 },
67 serverVersion: PEERTUBE_VERSION,
68 serverCommit,
69 signup: {
70 allowed,
71 allowedForCurrentIP,
72 requiresEmailVerification: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION
73 },
74 transcoding: {
75 hls: {
76 enabled: CONFIG.TRANSCODING.HLS.ENABLED
77 },
78 webtorrent: {
79 enabled: CONFIG.TRANSCODING.WEBTORRENT.ENABLED
80 },
81 enabledResolutions: getEnabledResolutions('vod'),
82 profile: CONFIG.TRANSCODING.PROFILE,
83 availableProfiles: VideoTranscodingProfilesManager.Instance.getAvailableProfiles('vod')
84 },
85 live: {
86 enabled: CONFIG.LIVE.ENABLED,
87
88 allowReplay: CONFIG.LIVE.ALLOW_REPLAY,
89 maxDuration: CONFIG.LIVE.MAX_DURATION,
90 maxInstanceLives: CONFIG.LIVE.MAX_INSTANCE_LIVES,
91 maxUserLives: CONFIG.LIVE.MAX_USER_LIVES,
92
93 transcoding: {
94 enabled: CONFIG.LIVE.TRANSCODING.ENABLED,
95 enabledResolutions: getEnabledResolutions('live'),
96 profile: CONFIG.LIVE.TRANSCODING.PROFILE,
97 availableProfiles: VideoTranscodingProfilesManager.Instance.getAvailableProfiles('live')
98 },
99
100 rtmp: {
101 port: CONFIG.LIVE.RTMP.PORT
102 }
103 },
104 import: {
105 videos: {
106 http: {
107 enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED
108 },
109 torrent: {
110 enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED
111 }
112 }
113 },
114 autoBlacklist: {
115 videos: {
116 ofUsers: {
117 enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED
118 }
119 }
120 },
121 avatar: {
122 file: {
123 size: {
124 max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max
125 },
126 extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME
127 }
128 },
129 banner: {
130 file: {
131 size: {
132 max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max
133 },
134 extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME
135 }
136 },
137 video: {
138 image: {
139 extensions: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME,
140 size: {
141 max: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max
142 }
143 },
144 file: {
145 extensions: CONSTRAINTS_FIELDS.VIDEOS.EXTNAME
146 }
147 },
148 videoCaption: {
149 file: {
150 size: {
151 max: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.FILE_SIZE.max
152 },
153 extensions: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.EXTNAME
154 }
155 },
156 user: {
157 videoQuota: CONFIG.USER.VIDEO_QUOTA,
158 videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY
159 },
160 trending: {
161 videos: {
162 intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS,
163 algorithms: {
164 enabled: CONFIG.TRENDING.VIDEOS.ALGORITHMS.ENABLED,
165 default: CONFIG.TRENDING.VIDEOS.ALGORITHMS.DEFAULT
166 }
167 }
168 },
169 tracker: {
170 enabled: CONFIG.TRACKER.ENABLED
171 },
172
173 followings: {
174 instance: {
175 autoFollowIndex: {
176 indexUrl: CONFIG.FOLLOWINGS.INSTANCE.AUTO_FOLLOW_INDEX.INDEX_URL
177 }
178 }
179 },
180
181 broadcastMessage: {
182 enabled: CONFIG.BROADCAST_MESSAGE.ENABLED,
183 message: CONFIG.BROADCAST_MESSAGE.MESSAGE,
184 level: CONFIG.BROADCAST_MESSAGE.LEVEL,
185 dismissable: CONFIG.BROADCAST_MESSAGE.DISMISSABLE
186 }
187 }
188}
189
190function getRegisteredThemes () {
191 return PluginManager.Instance.getRegisteredThemes()
192 .map(t => ({
193 name: t.name,
194 version: t.version,
195 description: t.description,
196 css: t.css,
197 clientScripts: t.clientScripts
198 }))
199}
200
201function getRegisteredPlugins () {
202 return PluginManager.Instance.getRegisteredPlugins()
203 .map(p => ({
204 name: p.name,
205 version: p.version,
206 description: p.description,
207 clientScripts: p.clientScripts
208 }))
209}
210
211// ---------------------------------------------------------------------------
212
213export {
214 getServerConfig,
215 getRegisteredThemes,
216 getRegisteredPlugins
217}
218
219// ---------------------------------------------------------------------------
220
221function getIdAndPassAuthPlugins () {
222 const result: RegisteredIdAndPassAuthConfig[] = []
223
224 for (const p of PluginManager.Instance.getIdAndPassAuths()) {
225 for (const auth of p.idAndPassAuths) {
226 result.push({
227 npmName: p.npmName,
228 name: p.name,
229 version: p.version,
230 authName: auth.authName,
231 weight: auth.getWeight()
232 })
233 }
234 }
235
236 return result
237}
238
239function getExternalAuthsPlugins () {
240 const result: RegisteredExternalAuthConfig[] = []
241
242 for (const p of PluginManager.Instance.getExternalAuths()) {
243 for (const auth of p.externalAuths) {
244 result.push({
245 npmName: p.npmName,
246 name: p.name,
247 version: p.version,
248 authName: auth.authName,
249 authDisplayName: auth.authDisplayName()
250 })
251 }
252 }
253
254 return result
255}
diff --git a/server/lib/plugins/plugin-helpers-builder.ts b/server/lib/plugins/plugin-helpers-builder.ts
index dac6b3185..cbd849742 100644
--- a/server/lib/plugins/plugin-helpers-builder.ts
+++ b/server/lib/plugins/plugin-helpers-builder.ts
@@ -12,8 +12,10 @@ import { VideoBlacklistCreate } from '@shared/models'
12import { blacklistVideo, unblacklistVideo } from '../video-blacklist' 12import { blacklistVideo, unblacklistVideo } from '../video-blacklist'
13import { VideoBlacklistModel } from '@server/models/video/video-blacklist' 13import { VideoBlacklistModel } from '@server/models/video/video-blacklist'
14import { AccountBlocklistModel } from '@server/models/account/account-blocklist' 14import { AccountBlocklistModel } from '@server/models/account/account-blocklist'
15import { getServerConfig } from '../config'
16import { MPlugin } from '@server/types/models'
15 17
16function buildPluginHelpers (npmName: string): PeerTubeHelpers { 18function buildPluginHelpers (pluginModel: MPlugin, npmName: string): PeerTubeHelpers {
17 const logger = buildPluginLogger(npmName) 19 const logger = buildPluginLogger(npmName)
18 20
19 const database = buildDatabaseHelpers() 21 const database = buildDatabaseHelpers()
@@ -25,12 +27,15 @@ function buildPluginHelpers (npmName: string): PeerTubeHelpers {
25 27
26 const moderation = buildModerationHelpers() 28 const moderation = buildModerationHelpers()
27 29
30 const plugin = buildPluginRelatedHelpers(pluginModel)
31
28 return { 32 return {
29 logger, 33 logger,
30 database, 34 database,
31 videos, 35 videos,
32 config, 36 config,
33 moderation, 37 moderation,
38 plugin,
34 server 39 server
35 } 40 }
36} 41}
@@ -132,6 +137,16 @@ function buildConfigHelpers () {
132 return { 137 return {
133 getWebserverUrl () { 138 getWebserverUrl () {
134 return WEBSERVER.URL 139 return WEBSERVER.URL
140 },
141
142 getServerConfig () {
143 return getServerConfig()
135 } 144 }
136 } 145 }
137} 146}
147
148function buildPluginRelatedHelpers (plugin: MPlugin) {
149 return {
150 getBaseStaticRoute: () => `/plugins/${plugin.name}/${plugin.version}/static/`
151 }
152}
diff --git a/server/lib/plugins/register-helpers.ts b/server/lib/plugins/register-helpers.ts
index 9b5e1a546..c018e54a8 100644
--- a/server/lib/plugins/register-helpers.ts
+++ b/server/lib/plugins/register-helpers.ts
@@ -109,7 +109,7 @@ export class RegisterHelpers {
109 const unregisterIdAndPassAuth = this.buildUnregisterIdAndPassAuth() 109 const unregisterIdAndPassAuth = this.buildUnregisterIdAndPassAuth()
110 const unregisterExternalAuth = this.buildUnregisterExternalAuth() 110 const unregisterExternalAuth = this.buildUnregisterExternalAuth()
111 111
112 const peertubeHelpers = buildPluginHelpers(this.npmName) 112 const peertubeHelpers = buildPluginHelpers(this.plugin, this.npmName)
113 113
114 return { 114 return {
115 registerHook, 115 registerHook,
diff --git a/server/tests/fixtures/peertube-plugin-test-four/main.js b/server/tests/fixtures/peertube-plugin-test-four/main.js
index 8df456c8a..ea0599997 100644
--- a/server/tests/fixtures/peertube-plugin-test-four/main.js
+++ b/server/tests/fixtures/peertube-plugin-test-four/main.js
@@ -69,7 +69,20 @@ async function register ({
69 res.sendStatus(500) 69 res.sendStatus(500)
70 } 70 }
71 }) 71 })
72
73 router.get('/server-config', async (req, res) => {
74 const serverConfig = await peertubeHelpers.config.getServerConfig()
75
76 return res.json({ serverConfig })
77 })
78
79 router.get('/static-route', async (req, res) => {
80 const staticRoute = await peertubeHelpers.plugin.getBaseStaticRoute()
81
82 return res.json({ staticRoute })
83 })
72 } 84 }
85
73} 86}
74 87
75async function unregister () { 88async function unregister () {
diff --git a/server/tests/plugins/plugin-helpers.ts b/server/tests/plugins/plugin-helpers.ts
index a585e3020..325d20e84 100644
--- a/server/tests/plugins/plugin-helpers.ts
+++ b/server/tests/plugins/plugin-helpers.ts
@@ -12,7 +12,8 @@ import {
12 uploadVideoAndGetId, 12 uploadVideoAndGetId,
13 viewVideo, 13 viewVideo,
14 getVideosList, 14 getVideosList,
15 waitJobs 15 waitJobs,
16 makeGetRequest
16} from '../../../shared/extra-utils' 17} from '../../../shared/extra-utils'
17import { cleanupTests, flushAndRunMultipleServers, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers' 18import { cleanupTests, flushAndRunMultipleServers, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers'
18import { expect } from 'chai' 19import { expect } from 'chai'
@@ -68,6 +69,17 @@ describe('Test plugin helpers', function () {
68 it('Should have the correct webserver url', async function () { 69 it('Should have the correct webserver url', async function () {
69 await waitUntilLog(servers[0], `server url is http://localhost:${servers[0].port}`) 70 await waitUntilLog(servers[0], `server url is http://localhost:${servers[0].port}`)
70 }) 71 })
72
73 it('Should have the correct config', async function () {
74 const res = await makeGetRequest({
75 url: servers[0].url,
76 path: '/plugins/test-four/router/server-config',
77 statusCodeExpected: HttpStatusCode.OK_200
78 })
79
80 expect(res.body.serverConfig).to.exist
81 expect(res.body.serverConfig.instance.name).to.equal('PeerTube')
82 })
71 }) 83 })
72 84
73 describe('Server', function () { 85 describe('Server', function () {
@@ -77,6 +89,19 @@ describe('Test plugin helpers', function () {
77 }) 89 })
78 }) 90 })
79 91
92 describe('Plugin', function () {
93
94 it('Should get the base static route', async function () {
95 const res = await makeGetRequest({
96 url: servers[0].url,
97 path: '/plugins/test-four/router/static-route',
98 statusCodeExpected: HttpStatusCode.OK_200
99 })
100
101 expect(res.body.staticRoute).to.equal('/plugins/test-four/0.0.1/static/')
102 })
103 })
104
80 describe('Moderation', function () { 105 describe('Moderation', function () {
81 let videoUUIDServer1: string 106 let videoUUIDServer1: string
82 107
diff --git a/server/types/plugins/register-server-option.model.ts b/server/types/plugins/register-server-option.model.ts
index 1ca17e4ab..391dcc3f9 100644
--- a/server/types/plugins/register-server-option.model.ts
+++ b/server/types/plugins/register-server-option.model.ts
@@ -12,6 +12,7 @@ import {
12 PluginVideoPrivacyManager, 12 PluginVideoPrivacyManager,
13 RegisterServerHookOptions, 13 RegisterServerHookOptions,
14 RegisterServerSettingOptions, 14 RegisterServerSettingOptions,
15 ServerConfig,
15 VideoBlacklistCreate 16 VideoBlacklistCreate
16} from '@shared/models' 17} from '@shared/models'
17import { MVideoThumbnail } from '../models' 18import { MVideoThumbnail } from '../models'
@@ -37,6 +38,8 @@ export type PeerTubeHelpers = {
37 38
38 config: { 39 config: {
39 getWebserverUrl: () => string 40 getWebserverUrl: () => string
41
42 getServerConfig: () => Promise<ServerConfig>
40 } 43 }
41 44
42 moderation: { 45 moderation: {
@@ -52,6 +55,10 @@ export type PeerTubeHelpers = {
52 server: { 55 server: {
53 getServerActor: () => Promise<ActorModel> 56 getServerActor: () => Promise<ActorModel>
54 } 57 }
58
59 plugin: {
60 getBaseStaticRoute: () => string
61 }
55} 62}
56 63
57export type RegisterServerOptions = { 64export type RegisterServerOptions = {