aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/controllers/api/config.ts2
-rw-r--r--server/controllers/api/plugins.ts2
-rw-r--r--server/lib/plugins/plugin-manager.ts45
-rw-r--r--server/lib/plugins/register-helpers-store.ts12
-rw-r--r--server/tests/api/server/plugins.ts11
-rw-r--r--server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js4
-rw-r--r--server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js2
-rw-r--r--shared/models/plugins/plugin-settings-manager.model.ts2
-rw-r--r--shared/models/plugins/register-server-auth.model.ts2
9 files changed, 59 insertions, 23 deletions
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
index 85f3ad3d9..edcb0b99e 100644
--- a/server/controllers/api/config.ts
+++ b/server/controllers/api/config.ts
@@ -299,7 +299,7 @@ function getExternalAuthsPlugins () {
299 name: p.name, 299 name: p.name,
300 version: p.version, 300 version: p.version,
301 authName: auth.authName, 301 authName: auth.authName,
302 authDisplayName: auth.authDisplayName 302 authDisplayName: auth.authDisplayName()
303 }) 303 })
304 } 304 }
305 } 305 }
diff --git a/server/controllers/api/plugins.ts b/server/controllers/api/plugins.ts
index 6b7562fd3..f8a0d19ca 100644
--- a/server/controllers/api/plugins.ts
+++ b/server/controllers/api/plugins.ts
@@ -191,6 +191,8 @@ async function updatePluginSettings (req: express.Request, res: express.Response
191 plugin.settings = req.body.settings 191 plugin.settings = req.body.settings
192 await plugin.save() 192 await plugin.save()
193 193
194 await PluginManager.Instance.onSettingsChanged(plugin.name, plugin.settings)
195
194 return res.sendStatus(204) 196 return res.sendStatus(204)
195} 197}
196 198
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts
index f7b84b1ff..950acf7ad 100644
--- a/server/lib/plugins/plugin-manager.ts
+++ b/server/lib/plugins/plugin-manager.ts
@@ -144,20 +144,6 @@ export class PluginManager implements ServerHook {
144 return this.translations[locale] || {} 144 return this.translations[locale] || {}
145 } 145 }
146 146
147 onLogout (npmName: string, authName: string, user: MUser) {
148 const auth = this.getAuth(npmName, authName)
149
150 if (auth?.onLogout) {
151 logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName)
152
153 try {
154 auth.onLogout(user)
155 } catch (err) {
156 logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err })
157 }
158 }
159 }
160
161 async isTokenValid (token: MOAuthTokenUser, type: 'access' | 'refresh') { 147 async isTokenValid (token: MOAuthTokenUser, type: 'access' | 'refresh') {
162 const auth = this.getAuth(token.User.pluginAuth, token.authName) 148 const auth = this.getAuth(token.User.pluginAuth, token.authName)
163 if (!auth) return true 149 if (!auth) return true
@@ -180,6 +166,37 @@ export class PluginManager implements ServerHook {
180 return true 166 return true
181 } 167 }
182 168
169 // ###################### External events ######################
170
171 onLogout (npmName: string, authName: string, user: MUser) {
172 const auth = this.getAuth(npmName, authName)
173
174 if (auth?.onLogout) {
175 logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName)
176
177 try {
178 auth.onLogout(user)
179 } catch (err) {
180 logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err })
181 }
182 }
183 }
184
185 onSettingsChanged (name: string, settings: any) {
186 const registered = this.getRegisteredPluginByShortName(name)
187 if (!registered) {
188 logger.error('Cannot find plugin %s to call on settings changed.', name)
189 }
190
191 for (const cb of registered.registerHelpersStore.getOnSettingsChangedCallbacks()) {
192 try {
193 cb(settings)
194 } catch (err) {
195 logger.error('Cannot run on settings changed callback for %s.', registered.npmName, { err })
196 }
197 }
198 }
199
183 // ###################### Hooks ###################### 200 // ###################### Hooks ######################
184 201
185 async runHook<T> (hookName: ServerHookName, result?: T, params?: any): Promise<T> { 202 async runHook<T> (hookName: ServerHookName, result?: T, params?: any): Promise<T> {
diff --git a/server/lib/plugins/register-helpers-store.ts b/server/lib/plugins/register-helpers-store.ts
index 151196bf1..6317ac2cf 100644
--- a/server/lib/plugins/register-helpers-store.ts
+++ b/server/lib/plugins/register-helpers-store.ts
@@ -52,6 +52,8 @@ export class RegisterHelpersStore {
52 private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = [] 52 private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = []
53 private readonly externalAuths: RegisterServerAuthExternalOptions[] = [] 53 private readonly externalAuths: RegisterServerAuthExternalOptions[] = []
54 54
55 private readonly onSettingsChangeCallbacks: ((settings: any) => void)[] = []
56
55 private readonly router: express.Router 57 private readonly router: express.Router
56 58
57 constructor ( 59 constructor (
@@ -149,6 +151,10 @@ export class RegisterHelpersStore {
149 return this.externalAuths 151 return this.externalAuths
150 } 152 }
151 153
154 getOnSettingsChangedCallbacks () {
155 return this.onSettingsChangeCallbacks
156 }
157
152 private buildGetRouter () { 158 private buildGetRouter () {
153 return () => this.router 159 return () => this.router
154 } 160 }
@@ -185,7 +191,7 @@ export class RegisterHelpersStore {
185 const self = this 191 const self = this
186 192
187 return (options: RegisterServerAuthExternalOptions) => { 193 return (options: RegisterServerAuthExternalOptions) => {
188 if (!options.authName || !options.onAuthRequest || typeof options.onAuthRequest !== 'function') { 194 if (!options.authName || typeof options.authDisplayName !== 'function' || typeof options.onAuthRequest !== 'function') {
189 logger.error('Cannot register auth plugin %s: authName of getWeight or login are not valid.', this.npmName) 195 logger.error('Cannot register auth plugin %s: authName of getWeight or login are not valid.', this.npmName)
190 return 196 return
191 } 197 }
@@ -212,7 +218,9 @@ export class RegisterHelpersStore {
212 218
213 getSettings: (names: string[]) => PluginModel.getSettings(this.plugin.name, this.plugin.type, names), 219 getSettings: (names: string[]) => PluginModel.getSettings(this.plugin.name, this.plugin.type, names),
214 220
215 setSetting: (name: string, value: string) => PluginModel.setSetting(this.plugin.name, this.plugin.type, name, value) 221 setSetting: (name: string, value: string) => PluginModel.setSetting(this.plugin.name, this.plugin.type, name, value),
222
223 onSettingsChange: (cb: (settings: any) => void) => this.onSettingsChangeCallbacks.push(cb)
216 } 224 }
217 } 225 }
218 226
diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts
index 452d05012..9885be4e8 100644
--- a/server/tests/api/server/plugins.ts
+++ b/server/tests/api/server/plugins.ts
@@ -27,7 +27,8 @@ import {
27 updatePlugin, 27 updatePlugin,
28 updatePluginPackageJSON, 28 updatePluginPackageJSON,
29 updatePluginSettings, 29 updatePluginSettings,
30 wait 30 wait,
31 waitUntilLog
31} from '../../../../shared/extra-utils' 32} from '../../../../shared/extra-utils'
32import { PluginType } from '../../../../shared/models/plugins/plugin.type' 33import { PluginType } from '../../../../shared/models/plugins/plugin.type'
33import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' 34import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model'
@@ -142,7 +143,7 @@ describe('Test plugins', function () {
142 it('Should have the correct global css', async function () { 143 it('Should have the correct global css', async function () {
143 const res = await getPluginsCSS(server.url) 144 const res = await getPluginsCSS(server.url)
144 145
145 expect(res.text).to.contain('--mainBackgroundColor') 146 expect(res.text).to.contain('background-color: red')
146 }) 147 })
147 148
148 it('Should have the plugin loaded in the configuration', async function () { 149 it('Should have the plugin loaded in the configuration', async function () {
@@ -258,6 +259,12 @@ describe('Test plugins', function () {
258 }) 259 })
259 }) 260 })
260 261
262 it('Should have watched settings changes', async function () {
263 this.timeout(10000)
264
265 await waitUntilLog(server, 'Settings changed!')
266 })
267
261 it('Should get a plugin and a theme', async function () { 268 it('Should get a plugin and a theme', async function () {
262 { 269 {
263 const res = await getPlugin({ 270 const res = await getPlugin({
diff --git a/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js b/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js
index f29fd1f30..91c67e550 100644
--- a/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js
+++ b/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js
@@ -5,7 +5,7 @@ async function register ({
5 { 5 {
6 const result = registerExternalAuth({ 6 const result = registerExternalAuth({
7 authName: 'external-auth-1', 7 authName: 'external-auth-1',
8 authDisplayName: 'External Auth 1', 8 authDisplayName: () => 'External Auth 1',
9 onLogout: user => peertubeHelpers.logger.info('On logout %s', user.username), 9 onLogout: user => peertubeHelpers.logger.info('On logout %s', user.username),
10 onAuthRequest: (req, res) => { 10 onAuthRequest: (req, res) => {
11 const username = req.query.username 11 const username = req.query.username
@@ -23,7 +23,7 @@ async function register ({
23 { 23 {
24 const result = registerExternalAuth({ 24 const result = registerExternalAuth({
25 authName: 'external-auth-2', 25 authName: 'external-auth-2',
26 authDisplayName: 'External Auth 2', 26 authDisplayName: () => 'External Auth 2',
27 onAuthRequest: (req, res) => { 27 onAuthRequest: (req, res) => {
28 result.userAuthenticated({ 28 result.userAuthenticated({
29 req, 29 req,
diff --git a/server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js b/server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js
index 34fec1bb3..126905ffc 100644
--- a/server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js
+++ b/server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js
@@ -5,7 +5,7 @@ async function register ({
5 { 5 {
6 const result = registerExternalAuth({ 6 const result = registerExternalAuth({
7 authName: 'external-auth-3', 7 authName: 'external-auth-3',
8 authDisplayName: 'External Auth 3', 8 authDisplayName: () => 'External Auth 3',
9 onAuthRequest: (req, res) => { 9 onAuthRequest: (req, res) => {
10 result.userAuthenticated({ 10 result.userAuthenticated({
11 req, 11 req,
diff --git a/shared/models/plugins/plugin-settings-manager.model.ts b/shared/models/plugins/plugin-settings-manager.model.ts
index f83f53b8f..db88ae6e7 100644
--- a/shared/models/plugins/plugin-settings-manager.model.ts
+++ b/shared/models/plugins/plugin-settings-manager.model.ts
@@ -6,4 +6,6 @@ export interface PluginSettingsManager {
6 getSettings: (names: string[]) => Bluebird<{ [settingName: string]: string | boolean }> 6 getSettings: (names: string[]) => Bluebird<{ [settingName: string]: string | boolean }>
7 7
8 setSetting: (name: string, value: string) => Bluebird<any> 8 setSetting: (name: string, value: string) => Bluebird<any>
9
10 onSettingsChange: (cb: (names: string[]) => void) => void
9} 11}
diff --git a/shared/models/plugins/register-server-auth.model.ts b/shared/models/plugins/register-server-auth.model.ts
index 6539dc888..4ffce9456 100644
--- a/shared/models/plugins/register-server-auth.model.ts
+++ b/shared/models/plugins/register-server-auth.model.ts
@@ -42,7 +42,7 @@ export interface RegisterServerAuthPassOptions extends RegisterServerAuthBase {
42 42
43export interface RegisterServerAuthExternalOptions extends RegisterServerAuthBase { 43export interface RegisterServerAuthExternalOptions extends RegisterServerAuthBase {
44 // Will be displayed in a block next to the login form 44 // Will be displayed in a block next to the login form
45 authDisplayName: string 45 authDisplayName: () => string
46 46
47 onAuthRequest: (req: express.Request, res: express.Response) => void 47 onAuthRequest: (req: express.Request, res: express.Response) => void
48} 48}