mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
10411 (#12037)
* feat: add type to privilege maps deprecate old hooks that are used for adding new privileges, new hooks are static:privileges.global.init/static:privileges.categories.init * deprecate admin priv hooks * fix: if type doesnt exist default to 'other' * remove filter * fix: copy privilege functions to use new filter instead of indices allow static hooks to use sync functions * fix: openapi * test: fix template helper
This commit is contained in:
committed by
GitHub
parent
c1f873b302
commit
f1a80d48cc
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const util = require('util');
|
||||
const winston = require('winston');
|
||||
const plugins = require('.');
|
||||
const utils = require('../utils');
|
||||
@@ -38,6 +37,67 @@ Hooks._deprecated = new Map([
|
||||
since: 'v2.7.0',
|
||||
until: 'v3.0.0',
|
||||
}],
|
||||
['filter:privileges.global.list', {
|
||||
new: 'static:privileges.global.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.global.groups.list', {
|
||||
new: 'static:privileges.global.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.global.list_human', {
|
||||
new: 'static:privileges.global.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.global.groups.list_human', {
|
||||
new: 'static:privileges.global.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.list', {
|
||||
new: 'static:privileges.categories.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.groups.list', {
|
||||
new: 'static:privileges.categories.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.list_human', {
|
||||
new: 'static:privileges.categories.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.groups.list_human', {
|
||||
new: 'static:privileges.categories.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
|
||||
['filter:privileges.admin.list', {
|
||||
new: 'static:privileges.admin.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.admin.groups.list', {
|
||||
new: 'static:privileges.admin.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.admin.list_human', {
|
||||
new: 'static:privileges.admin.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
['filter:privileges.admin.groups.list_human', {
|
||||
new: 'static:privileges.admin.init',
|
||||
since: 'v3.5.0',
|
||||
until: 'v4.0.0',
|
||||
}],
|
||||
]);
|
||||
|
||||
Hooks.internals = {
|
||||
@@ -213,41 +273,6 @@ async function fireActionHook(hook, hookList, params) {
|
||||
}
|
||||
}
|
||||
|
||||
async function fireStaticHook(hook, hookList, params) {
|
||||
if (!Array.isArray(hookList) || !hookList.length) {
|
||||
return;
|
||||
}
|
||||
// don't bubble errors from these hooks, so bad plugins don't stop startup
|
||||
const noErrorHooks = ['static:app.load', 'static:assets.prepare', 'static:app.preload'];
|
||||
|
||||
for (const hookObj of hookList) {
|
||||
if (typeof hookObj.method !== 'function') {
|
||||
if (global.env === 'development') {
|
||||
winston.warn(`[plugins] Expected method for hook '${hook}' in plugin '${hookObj.id}' not found, skipping.`);
|
||||
}
|
||||
} else {
|
||||
let hookFn = hookObj.method;
|
||||
if (hookFn.constructor && hookFn.constructor.name !== 'AsyncFunction') {
|
||||
hookFn = util.promisify(hookFn);
|
||||
}
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
await timeout(hookFn(params), 10000, 'timeout');
|
||||
} catch (err) {
|
||||
if (err && err.message === 'timeout') {
|
||||
winston.warn(`[plugins] Callback timed out, hook '${hook}' in plugin '${hookObj.id}'`);
|
||||
} else {
|
||||
winston.error(`[plugins] Error executing '${hook}' in plugin '${hookObj.id}'\n${err.stack}`);
|
||||
if (!noErrorHooks.includes(hook)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://advancedweb.hu/how-to-add-timeout-to-a-promise-in-javascript/
|
||||
const timeout = (prom, time, error) => {
|
||||
let timer;
|
||||
@@ -259,6 +284,66 @@ const timeout = (prom, time, error) => {
|
||||
]).finally(() => clearTimeout(timer));
|
||||
};
|
||||
|
||||
async function fireStaticHook(hook, hookList, params) {
|
||||
if (!Array.isArray(hookList) || !hookList.length) {
|
||||
return;
|
||||
}
|
||||
// don't bubble errors from these hooks, so bad plugins don't stop startup
|
||||
const noErrorHooks = ['static:app.load', 'static:assets.prepare', 'static:app.preload'];
|
||||
|
||||
async function fireMethod(hookObj, params) {
|
||||
if (typeof hookObj.method !== 'function') {
|
||||
if (global.env === 'development') {
|
||||
winston.warn(`[plugins] Expected method for hook '${hook}' in plugin '${hookObj.id}' not found, skipping.`);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
if (hookObj.method.constructor && hookObj.method.constructor.name === 'AsyncFunction') {
|
||||
return timeout(hookObj.method(params), 10000, 'timeout');
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let resolved = false;
|
||||
function _resolve(result) {
|
||||
if (resolved) {
|
||||
return;
|
||||
}
|
||||
resolved = true;
|
||||
resolve(result);
|
||||
}
|
||||
const returned = hookObj.method(params, (err, result) => {
|
||||
if (err) reject(err); else _resolve(result);
|
||||
});
|
||||
|
||||
if (utils.isPromise(returned)) {
|
||||
returned.then(
|
||||
payload => _resolve(payload),
|
||||
err => reject(err)
|
||||
);
|
||||
return;
|
||||
}
|
||||
_resolve();
|
||||
});
|
||||
}
|
||||
|
||||
for (const hookObj of hookList) {
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
await fireMethod(hookObj, params);
|
||||
} catch (err) {
|
||||
if (err && err.message === 'timeout') {
|
||||
winston.warn(`[plugins] Callback timed out, hook '${hook}' in plugin '${hookObj.id}'`);
|
||||
} else {
|
||||
winston.error(`[plugins] Error executing '${hook}' in plugin '${hookObj.id}'\n${err.stack}`);
|
||||
if (!noErrorHooks.includes(hook)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function fireResponseHook(hook, hookList, params) {
|
||||
if (!Array.isArray(hookList) || !hookList.length) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user