Add plugin settings change watcher

This commit is contained in:
Chocobozzz 2020-04-30 09:28:39 +02:00 committed by Chocobozzz
parent dadc90bca2
commit a5896799f1
9 changed files with 59 additions and 23 deletions

View File

@ -299,7 +299,7 @@ function getExternalAuthsPlugins () {
name: p.name, name: p.name,
version: p.version, version: p.version,
authName: auth.authName, authName: auth.authName,
authDisplayName: auth.authDisplayName authDisplayName: auth.authDisplayName()
}) })
} }
} }

View File

@ -191,6 +191,8 @@ async function updatePluginSettings (req: express.Request, res: express.Response
plugin.settings = req.body.settings plugin.settings = req.body.settings
await plugin.save() await plugin.save()
await PluginManager.Instance.onSettingsChanged(plugin.name, plugin.settings)
return res.sendStatus(204) return res.sendStatus(204)
} }

View File

@ -144,20 +144,6 @@ export class PluginManager implements ServerHook {
return this.translations[locale] || {} return this.translations[locale] || {}
} }
onLogout (npmName: string, authName: string, user: MUser) {
const auth = this.getAuth(npmName, authName)
if (auth?.onLogout) {
logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName)
try {
auth.onLogout(user)
} catch (err) {
logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err })
}
}
}
async isTokenValid (token: MOAuthTokenUser, type: 'access' | 'refresh') { async isTokenValid (token: MOAuthTokenUser, type: 'access' | 'refresh') {
const auth = this.getAuth(token.User.pluginAuth, token.authName) const auth = this.getAuth(token.User.pluginAuth, token.authName)
if (!auth) return true if (!auth) return true
@ -180,6 +166,37 @@ export class PluginManager implements ServerHook {
return true return true
} }
// ###################### External events ######################
onLogout (npmName: string, authName: string, user: MUser) {
const auth = this.getAuth(npmName, authName)
if (auth?.onLogout) {
logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName)
try {
auth.onLogout(user)
} catch (err) {
logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err })
}
}
}
onSettingsChanged (name: string, settings: any) {
const registered = this.getRegisteredPluginByShortName(name)
if (!registered) {
logger.error('Cannot find plugin %s to call on settings changed.', name)
}
for (const cb of registered.registerHelpersStore.getOnSettingsChangedCallbacks()) {
try {
cb(settings)
} catch (err) {
logger.error('Cannot run on settings changed callback for %s.', registered.npmName, { err })
}
}
}
// ###################### Hooks ###################### // ###################### Hooks ######################
async runHook<T> (hookName: ServerHookName, result?: T, params?: any): Promise<T> { async runHook<T> (hookName: ServerHookName, result?: T, params?: any): Promise<T> {

View File

@ -52,6 +52,8 @@ export class RegisterHelpersStore {
private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = [] private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = []
private readonly externalAuths: RegisterServerAuthExternalOptions[] = [] private readonly externalAuths: RegisterServerAuthExternalOptions[] = []
private readonly onSettingsChangeCallbacks: ((settings: any) => void)[] = []
private readonly router: express.Router private readonly router: express.Router
constructor ( constructor (
@ -149,6 +151,10 @@ export class RegisterHelpersStore {
return this.externalAuths return this.externalAuths
} }
getOnSettingsChangedCallbacks () {
return this.onSettingsChangeCallbacks
}
private buildGetRouter () { private buildGetRouter () {
return () => this.router return () => this.router
} }
@ -185,7 +191,7 @@ export class RegisterHelpersStore {
const self = this const self = this
return (options: RegisterServerAuthExternalOptions) => { return (options: RegisterServerAuthExternalOptions) => {
if (!options.authName || !options.onAuthRequest || typeof options.onAuthRequest !== 'function') { if (!options.authName || typeof options.authDisplayName !== 'function' || typeof options.onAuthRequest !== 'function') {
logger.error('Cannot register auth plugin %s: authName of getWeight or login are not valid.', this.npmName) logger.error('Cannot register auth plugin %s: authName of getWeight or login are not valid.', this.npmName)
return return
} }
@ -212,7 +218,9 @@ export class RegisterHelpersStore {
getSettings: (names: string[]) => PluginModel.getSettings(this.plugin.name, this.plugin.type, names), getSettings: (names: string[]) => PluginModel.getSettings(this.plugin.name, this.plugin.type, names),
setSetting: (name: string, value: string) => PluginModel.setSetting(this.plugin.name, this.plugin.type, name, value) setSetting: (name: string, value: string) => PluginModel.setSetting(this.plugin.name, this.plugin.type, name, value),
onSettingsChange: (cb: (settings: any) => void) => this.onSettingsChangeCallbacks.push(cb)
} }
} }

View File

@ -27,7 +27,8 @@ import {
updatePlugin, updatePlugin,
updatePluginPackageJSON, updatePluginPackageJSON,
updatePluginSettings, updatePluginSettings,
wait wait,
waitUntilLog
} from '../../../../shared/extra-utils' } from '../../../../shared/extra-utils'
import { PluginType } from '../../../../shared/models/plugins/plugin.type' import { PluginType } from '../../../../shared/models/plugins/plugin.type'
import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model'
@ -142,7 +143,7 @@ describe('Test plugins', function () {
it('Should have the correct global css', async function () { it('Should have the correct global css', async function () {
const res = await getPluginsCSS(server.url) const res = await getPluginsCSS(server.url)
expect(res.text).to.contain('--mainBackgroundColor') expect(res.text).to.contain('background-color: red')
}) })
it('Should have the plugin loaded in the configuration', async function () { it('Should have the plugin loaded in the configuration', async function () {
@ -258,6 +259,12 @@ describe('Test plugins', function () {
}) })
}) })
it('Should have watched settings changes', async function () {
this.timeout(10000)
await waitUntilLog(server, 'Settings changed!')
})
it('Should get a plugin and a theme', async function () { it('Should get a plugin and a theme', async function () {
{ {
const res = await getPlugin({ const res = await getPlugin({

View File

@ -5,7 +5,7 @@ async function register ({
{ {
const result = registerExternalAuth({ const result = registerExternalAuth({
authName: 'external-auth-1', authName: 'external-auth-1',
authDisplayName: 'External Auth 1', authDisplayName: () => 'External Auth 1',
onLogout: user => peertubeHelpers.logger.info('On logout %s', user.username), onLogout: user => peertubeHelpers.logger.info('On logout %s', user.username),
onAuthRequest: (req, res) => { onAuthRequest: (req, res) => {
const username = req.query.username const username = req.query.username
@ -23,7 +23,7 @@ async function register ({
{ {
const result = registerExternalAuth({ const result = registerExternalAuth({
authName: 'external-auth-2', authName: 'external-auth-2',
authDisplayName: 'External Auth 2', authDisplayName: () => 'External Auth 2',
onAuthRequest: (req, res) => { onAuthRequest: (req, res) => {
result.userAuthenticated({ result.userAuthenticated({
req, req,

View File

@ -5,7 +5,7 @@ async function register ({
{ {
const result = registerExternalAuth({ const result = registerExternalAuth({
authName: 'external-auth-3', authName: 'external-auth-3',
authDisplayName: 'External Auth 3', authDisplayName: () => 'External Auth 3',
onAuthRequest: (req, res) => { onAuthRequest: (req, res) => {
result.userAuthenticated({ result.userAuthenticated({
req, req,

View File

@ -6,4 +6,6 @@ export interface PluginSettingsManager {
getSettings: (names: string[]) => Bluebird<{ [settingName: string]: string | boolean }> getSettings: (names: string[]) => Bluebird<{ [settingName: string]: string | boolean }>
setSetting: (name: string, value: string) => Bluebird<any> setSetting: (name: string, value: string) => Bluebird<any>
onSettingsChange: (cb: (names: string[]) => void) => void
} }

View File

@ -42,7 +42,7 @@ export interface RegisterServerAuthPassOptions extends RegisterServerAuthBase {
export interface RegisterServerAuthExternalOptions extends RegisterServerAuthBase { export interface RegisterServerAuthExternalOptions extends RegisterServerAuthBase {
// Will be displayed in a block next to the login form // Will be displayed in a block next to the login form
authDisplayName: string authDisplayName: () => string
onAuthRequest: (req: express.Request, res: express.Response) => void onAuthRequest: (req: express.Request, res: express.Response) => void
} }