diff options
Diffstat (limited to 'server/lib/plugins')
-rw-r--r-- | server/lib/plugins/plugin-manager.ts | 55 | ||||
-rw-r--r-- | server/lib/plugins/register-helpers-store.ts | 43 |
2 files changed, 80 insertions, 18 deletions
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts index 37fb07716..f78b989f5 100644 --- a/server/lib/plugins/plugin-manager.ts +++ b/server/lib/plugins/plugin-manager.ts | |||
@@ -39,6 +39,7 @@ export interface RegisteredPlugin { | |||
39 | css: string[] | 39 | css: string[] |
40 | 40 | ||
41 | // Only if this is a plugin | 41 | // Only if this is a plugin |
42 | registerHelpersStore?: RegisterHelpersStore | ||
42 | unregister?: Function | 43 | unregister?: Function |
43 | } | 44 | } |
44 | 45 | ||
@@ -58,11 +59,10 @@ export class PluginManager implements ServerHook { | |||
58 | private static instance: PluginManager | 59 | private static instance: PluginManager |
59 | 60 | ||
60 | private registeredPlugins: { [name: string]: RegisteredPlugin } = {} | 61 | private registeredPlugins: { [name: string]: RegisteredPlugin } = {} |
62 | |||
61 | private hooks: { [name: string]: HookInformationValue[] } = {} | 63 | private hooks: { [name: string]: HookInformationValue[] } = {} |
62 | private translations: PluginLocalesTranslations = {} | 64 | private translations: PluginLocalesTranslations = {} |
63 | 65 | ||
64 | private registerHelpersStore: { [npmName: string]: RegisterHelpersStore } = {} | ||
65 | |||
66 | private constructor () { | 66 | private constructor () { |
67 | } | 67 | } |
68 | 68 | ||
@@ -102,18 +102,30 @@ export class PluginManager implements ServerHook { | |||
102 | return this.getRegisteredPluginsOrThemes(PluginType.THEME) | 102 | return this.getRegisteredPluginsOrThemes(PluginType.THEME) |
103 | } | 103 | } |
104 | 104 | ||
105 | getIdAndPassAuths () { | ||
106 | return this.getRegisteredPlugins() | ||
107 | .map(p => ({ npmName: p.npmName, idAndPassAuths: p.registerHelpersStore.getIdAndPassAuths() })) | ||
108 | .filter(v => v.idAndPassAuths.length !== 0) | ||
109 | } | ||
110 | |||
111 | getExternalAuths () { | ||
112 | return this.getRegisteredPlugins() | ||
113 | .map(p => ({ npmName: p.npmName, externalAuths: p.registerHelpersStore.getExternalAuths() })) | ||
114 | .filter(v => v.externalAuths.length !== 0) | ||
115 | } | ||
116 | |||
105 | getRegisteredSettings (npmName: string) { | 117 | getRegisteredSettings (npmName: string) { |
106 | const store = this.registerHelpersStore[npmName] | 118 | const result = this.getRegisteredPluginOrTheme(npmName) |
107 | if (store) return store.getSettings() | 119 | if (!result || result.type !== PluginType.PLUGIN) return [] |
108 | 120 | ||
109 | return [] | 121 | return result.registerHelpersStore.getSettings() |
110 | } | 122 | } |
111 | 123 | ||
112 | getRouter (npmName: string) { | 124 | getRouter (npmName: string) { |
113 | const store = this.registerHelpersStore[npmName] | 125 | const result = this.getRegisteredPluginOrTheme(npmName) |
114 | if (!store) return null | 126 | if (!result || result.type !== PluginType.PLUGIN) return null |
115 | 127 | ||
116 | return store.getRouter() | 128 | return result.registerHelpersStore.getRouter() |
117 | } | 129 | } |
118 | 130 | ||
119 | getTranslations (locale: string) { | 131 | getTranslations (locale: string) { |
@@ -185,11 +197,9 @@ export class PluginManager implements ServerHook { | |||
185 | this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName) | 197 | this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName) |
186 | } | 198 | } |
187 | 199 | ||
188 | const store = this.registerHelpersStore[plugin.npmName] | 200 | const store = plugin.registerHelpersStore |
189 | store.reinitVideoConstants(plugin.npmName) | 201 | store.reinitVideoConstants(plugin.npmName) |
190 | 202 | ||
191 | delete this.registerHelpersStore[plugin.npmName] | ||
192 | |||
193 | logger.info('Regenerating registered plugin CSS to global file.') | 203 | logger.info('Regenerating registered plugin CSS to global file.') |
194 | await this.regeneratePluginGlobalCSS() | 204 | await this.regeneratePluginGlobalCSS() |
195 | } | 205 | } |
@@ -294,8 +304,11 @@ export class PluginManager implements ServerHook { | |||
294 | this.sanitizeAndCheckPackageJSONOrThrow(packageJSON, plugin.type) | 304 | this.sanitizeAndCheckPackageJSONOrThrow(packageJSON, plugin.type) |
295 | 305 | ||
296 | let library: PluginLibrary | 306 | let library: PluginLibrary |
307 | let registerHelpersStore: RegisterHelpersStore | ||
297 | if (plugin.type === PluginType.PLUGIN) { | 308 | if (plugin.type === PluginType.PLUGIN) { |
298 | library = await this.registerPlugin(plugin, pluginPath, packageJSON) | 309 | const result = await this.registerPlugin(plugin, pluginPath, packageJSON) |
310 | library = result.library | ||
311 | registerHelpersStore = result.registerStore | ||
299 | } | 312 | } |
300 | 313 | ||
301 | const clientScripts: { [id: string]: ClientScript } = {} | 314 | const clientScripts: { [id: string]: ClientScript } = {} |
@@ -314,6 +327,7 @@ export class PluginManager implements ServerHook { | |||
314 | staticDirs: packageJSON.staticDirs, | 327 | staticDirs: packageJSON.staticDirs, |
315 | clientScripts, | 328 | clientScripts, |
316 | css: packageJSON.css, | 329 | css: packageJSON.css, |
330 | registerHelpersStore: registerHelpersStore || undefined, | ||
317 | unregister: library ? library.unregister : undefined | 331 | unregister: library ? library.unregister : undefined |
318 | } | 332 | } |
319 | 333 | ||
@@ -332,15 +346,15 @@ export class PluginManager implements ServerHook { | |||
332 | throw new Error('Library code is not valid (miss register or unregister function)') | 346 | throw new Error('Library code is not valid (miss register or unregister function)') |
333 | } | 347 | } |
334 | 348 | ||
335 | const registerHelpers = this.getRegisterHelpers(npmName, plugin) | 349 | const { registerOptions, registerStore } = this.getRegisterHelpers(npmName, plugin) |
336 | library.register(registerHelpers) | 350 | library.register(registerOptions) |
337 | .catch(err => logger.error('Cannot register plugin %s.', npmName, { err })) | 351 | .catch(err => logger.error('Cannot register plugin %s.', npmName, { err })) |
338 | 352 | ||
339 | logger.info('Add plugin %s CSS to global file.', npmName) | 353 | logger.info('Add plugin %s CSS to global file.', npmName) |
340 | 354 | ||
341 | await this.addCSSToGlobalFile(pluginPath, packageJSON.css) | 355 | await this.addCSSToGlobalFile(pluginPath, packageJSON.css) |
342 | 356 | ||
343 | return library | 357 | return { library, registerStore } |
344 | } | 358 | } |
345 | 359 | ||
346 | // ###################### Translations ###################### | 360 | // ###################### Translations ###################### |
@@ -440,7 +454,10 @@ export class PluginManager implements ServerHook { | |||
440 | 454 | ||
441 | // ###################### Generate register helpers ###################### | 455 | // ###################### Generate register helpers ###################### |
442 | 456 | ||
443 | private getRegisterHelpers (npmName: string, plugin: PluginModel): RegisterServerOptions { | 457 | private getRegisterHelpers ( |
458 | npmName: string, | ||
459 | plugin: PluginModel | ||
460 | ): { registerStore: RegisterHelpersStore, registerOptions: RegisterServerOptions } { | ||
444 | const onHookAdded = (options: RegisterServerHookOptions) => { | 461 | const onHookAdded = (options: RegisterServerHookOptions) => { |
445 | if (!this.hooks[options.target]) this.hooks[options.target] = [] | 462 | if (!this.hooks[options.target]) this.hooks[options.target] = [] |
446 | 463 | ||
@@ -453,9 +470,11 @@ export class PluginManager implements ServerHook { | |||
453 | } | 470 | } |
454 | 471 | ||
455 | const registerHelpersStore = new RegisterHelpersStore(npmName, plugin, onHookAdded.bind(this)) | 472 | const registerHelpersStore = new RegisterHelpersStore(npmName, plugin, onHookAdded.bind(this)) |
456 | this.registerHelpersStore[npmName] = registerHelpersStore | ||
457 | 473 | ||
458 | return registerHelpersStore.buildRegisterHelpers() | 474 | return { |
475 | registerStore: registerHelpersStore, | ||
476 | registerOptions: registerHelpersStore.buildRegisterHelpers() | ||
477 | } | ||
459 | } | 478 | } |
460 | 479 | ||
461 | private sanitizeAndCheckPackageJSONOrThrow (packageJSON: PluginPackageJson, pluginType: PluginType) { | 480 | private sanitizeAndCheckPackageJSONOrThrow (packageJSON: PluginPackageJson, pluginType: PluginType) { |
diff --git a/server/lib/plugins/register-helpers-store.ts b/server/lib/plugins/register-helpers-store.ts index 5ca52b151..7e827401f 100644 --- a/server/lib/plugins/register-helpers-store.ts +++ b/server/lib/plugins/register-helpers-store.ts | |||
@@ -20,6 +20,12 @@ import { RegisterServerSettingOptions } from '@shared/models/plugins/register-se | |||
20 | import * as express from 'express' | 20 | import * as express from 'express' |
21 | import { PluginVideoPrivacyManager } from '@shared/models/plugins/plugin-video-privacy-manager.model' | 21 | import { PluginVideoPrivacyManager } from '@shared/models/plugins/plugin-video-privacy-manager.model' |
22 | import { PluginPlaylistPrivacyManager } from '@shared/models/plugins/plugin-playlist-privacy-manager.model' | 22 | import { PluginPlaylistPrivacyManager } from '@shared/models/plugins/plugin-playlist-privacy-manager.model' |
23 | import { | ||
24 | RegisterServerAuthExternalOptions, | ||
25 | RegisterServerAuthExternalResult, | ||
26 | RegisterServerAuthPassOptions | ||
27 | } from '@shared/models/plugins/register-server-auth.model' | ||
28 | import { onExternalAuthPlugin } from '@server/lib/auth' | ||
23 | 29 | ||
24 | type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' | 30 | type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' |
25 | type VideoConstant = { [key in number | string]: string } | 31 | type VideoConstant = { [key in number | string]: string } |
@@ -42,6 +48,9 @@ export class RegisterHelpersStore { | |||
42 | 48 | ||
43 | private readonly settings: RegisterServerSettingOptions[] = [] | 49 | private readonly settings: RegisterServerSettingOptions[] = [] |
44 | 50 | ||
51 | private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = [] | ||
52 | private readonly externalAuths: RegisterServerAuthExternalOptions[] = [] | ||
53 | |||
45 | private readonly router: express.Router | 54 | private readonly router: express.Router |
46 | 55 | ||
47 | constructor ( | 56 | constructor ( |
@@ -69,6 +78,9 @@ export class RegisterHelpersStore { | |||
69 | const videoPrivacyManager = this.buildVideoPrivacyManager() | 78 | const videoPrivacyManager = this.buildVideoPrivacyManager() |
70 | const playlistPrivacyManager = this.buildPlaylistPrivacyManager() | 79 | const playlistPrivacyManager = this.buildPlaylistPrivacyManager() |
71 | 80 | ||
81 | const registerIdAndPassAuth = this.buildRegisterIdAndPassAuth() | ||
82 | const registerExternalAuth = this.buildRegisterExternalAuth() | ||
83 | |||
72 | const peertubeHelpers = buildPluginHelpers(this.npmName) | 84 | const peertubeHelpers = buildPluginHelpers(this.npmName) |
73 | 85 | ||
74 | return { | 86 | return { |
@@ -87,6 +99,9 @@ export class RegisterHelpersStore { | |||
87 | videoPrivacyManager, | 99 | videoPrivacyManager, |
88 | playlistPrivacyManager, | 100 | playlistPrivacyManager, |
89 | 101 | ||
102 | registerIdAndPassAuth, | ||
103 | registerExternalAuth, | ||
104 | |||
90 | peertubeHelpers | 105 | peertubeHelpers |
91 | } | 106 | } |
92 | } | 107 | } |
@@ -125,6 +140,14 @@ export class RegisterHelpersStore { | |||
125 | return this.router | 140 | return this.router |
126 | } | 141 | } |
127 | 142 | ||
143 | getIdAndPassAuths () { | ||
144 | return this.idAndPassAuths | ||
145 | } | ||
146 | |||
147 | getExternalAuths () { | ||
148 | return this.externalAuths | ||
149 | } | ||
150 | |||
128 | private buildGetRouter () { | 151 | private buildGetRouter () { |
129 | return () => this.router | 152 | return () => this.router |
130 | } | 153 | } |
@@ -146,6 +169,26 @@ export class RegisterHelpersStore { | |||
146 | } | 169 | } |
147 | } | 170 | } |
148 | 171 | ||
172 | private buildRegisterIdAndPassAuth () { | ||
173 | return (options: RegisterServerAuthPassOptions) => { | ||
174 | this.idAndPassAuths.push(options) | ||
175 | } | ||
176 | } | ||
177 | |||
178 | private buildRegisterExternalAuth () { | ||
179 | const self = this | ||
180 | |||
181 | return (options: RegisterServerAuthExternalOptions) => { | ||
182 | this.externalAuths.push(options) | ||
183 | |||
184 | return { | ||
185 | onAuth (options: { username: string, email: string }): void { | ||
186 | onExternalAuthPlugin(self.npmName, options.username, options.email) | ||
187 | } | ||
188 | } as RegisterServerAuthExternalResult | ||
189 | } | ||
190 | } | ||
191 | |||
149 | private buildSettingsManager (): PluginSettingsManager { | 192 | private buildSettingsManager (): PluginSettingsManager { |
150 | return { | 193 | return { |
151 | getSetting: (name: string) => PluginModel.getSetting(this.plugin.name, this.plugin.type, name), | 194 | getSetting: (name: string) => PluginModel.getSetting(this.plugin.name, this.plugin.type, name), |