mirror of
https://github.com/wassname/talk.git
synced 2026-06-29 23:09:26 +08:00
131 lines
3.3 KiB
JavaScript
131 lines
3.3 KiB
JavaScript
const errors = require('../../errors');
|
|
const get = require('lodash/get');
|
|
|
|
// Load in the phases to use.
|
|
const {
|
|
wordlist,
|
|
commentLength,
|
|
assetClosed,
|
|
karma,
|
|
staff,
|
|
links,
|
|
premod,
|
|
} = require('./phases');
|
|
|
|
// This phase checks to see if the comment was already prescribed a status. This
|
|
// essentially provides a hook for plugins to inject their own comments.
|
|
const applyPreexisting = (ctx, comment) => {
|
|
const status = get(comment, 'status');
|
|
|
|
// If the status was already defined, don't redefine it. It's only defined
|
|
// when specific external conditions exist, we don't want to override that.
|
|
if (status) {
|
|
return {
|
|
status,
|
|
};
|
|
}
|
|
};
|
|
|
|
// Applies the defaulted status.
|
|
const applyStatus = status => () => ({ status });
|
|
|
|
/**
|
|
* phases is an array of moderation phases carried out in order until a status is
|
|
* returned.
|
|
*/
|
|
const phases = [
|
|
commentLength,
|
|
assetClosed,
|
|
wordlist,
|
|
staff,
|
|
links,
|
|
karma,
|
|
applyPreexisting,
|
|
premod,
|
|
applyStatus('NONE'),
|
|
];
|
|
|
|
/**
|
|
* compose will create a moderation pipeline for which is executable with the
|
|
* passed actions.
|
|
*
|
|
* @param {Array} phases the set of moderation phases to pass the comment and
|
|
* their options through.
|
|
*/
|
|
const compose = phases => async (ctx, comment, options) => {
|
|
const actions = get(comment, 'actions', []);
|
|
|
|
// Loop over all the moderation phases and see if we've resolved the status.
|
|
for (const phase of phases) {
|
|
const result = await phase(ctx, comment, options);
|
|
if (result) {
|
|
if (result.actions) {
|
|
actions.push(...result.actions);
|
|
}
|
|
|
|
// If this result contained a status, then we've finished resolving
|
|
// phases!
|
|
if (result.status) {
|
|
return { status: result.status, actions };
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* fetchOptions will generate the options used by the moderation service to
|
|
* determine the end status.
|
|
*
|
|
* @param {Object} ctx graph context
|
|
* @param {Object} comment comment object to use
|
|
*/
|
|
const fetchOptions = async (ctx, comment) => {
|
|
const {
|
|
connectors: { services: { Assets: AssetsService } },
|
|
loaders: { Settings, Assets },
|
|
} = ctx;
|
|
|
|
// Load the settings.
|
|
const settings = await Settings.load();
|
|
|
|
// Pull the asset id out of the comment.
|
|
const assetID = get(comment, 'asset_id', null);
|
|
if (assetID === null) {
|
|
// And leave now if this asset wasn't found.
|
|
throw errors.ErrNotFound;
|
|
}
|
|
|
|
// Load the asset.
|
|
const asset = await Assets.getByID.load(assetID);
|
|
if (!asset) {
|
|
// And leave now if this asset wasn't found.
|
|
throw errors.ErrNotFound;
|
|
}
|
|
|
|
// Combine the asset and the settings to get the asset settings.
|
|
asset.settings = await AssetsService.rectifySettings(asset, settings);
|
|
|
|
// Create the options that will be consumed by the phases.
|
|
return {
|
|
asset,
|
|
settings,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* process the comment and return moderation details.
|
|
*
|
|
* @param {Object} ctx graphql context
|
|
* @param {Object} comment comment to perform the moderation phases on
|
|
*/
|
|
const process = async (ctx, comment) => {
|
|
// Fetch the options to use for the moderation phases.
|
|
const options = await fetchOptions(ctx, comment);
|
|
|
|
// Compose a moderation pipeline from the moderation phases and execute it on
|
|
// the comment.
|
|
return compose(phases)(ctx, comment, options);
|
|
};
|
|
|
|
module.exports.process = process;
|