Renaming 'moderation' pages to 'configuration'.
This commit is contained in:
62
server/lib/configuration/channel/sanitize.ts
Normal file
62
server/lib/configuration/channel/sanitize.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import type { RegisterServerOptions } from '@peertube/peertube-types'
|
||||
import type { ChannelConfigurationOptions, ChannelInfos } from '../../../../shared/lib/types'
|
||||
|
||||
/**
|
||||
* Sanitize data so that they can safely be used/stored for channel configuration configuration.
|
||||
* Throw an error if the format is obviously wrong.
|
||||
* Cleans data (removing empty values, ...)
|
||||
* @param options Peertube server options
|
||||
* @param _channelInfos Channel infos
|
||||
* @param data Input data
|
||||
*/
|
||||
async function sanitizeChannelConfigurationOptions (
|
||||
_options: RegisterServerOptions,
|
||||
_channelInfos: ChannelInfos,
|
||||
data: any
|
||||
): Promise<ChannelConfigurationOptions> {
|
||||
const result = {
|
||||
bot: false,
|
||||
bannedJIDs: [],
|
||||
forbiddenWords: []
|
||||
}
|
||||
|
||||
if (typeof data !== 'object') {
|
||||
throw new Error('Invalid data type')
|
||||
}
|
||||
// boolean fields
|
||||
for (const f of ['bot']) {
|
||||
if (!(f in data) || (typeof data[f] !== 'boolean')) {
|
||||
throw new Error('Invalid data type for field ' + f)
|
||||
}
|
||||
result[f as keyof ChannelConfigurationOptions] = data[f]
|
||||
}
|
||||
// value/regexp array fields
|
||||
for (const f of ['bannedJIDs', 'forbiddenWords']) {
|
||||
if (!(f in data) || !Array.isArray(data[f])) {
|
||||
throw new Error('Invalid data type for field ' + f)
|
||||
}
|
||||
for (const v of data[f]) {
|
||||
if (typeof v !== 'string') {
|
||||
throw new Error('Invalid data type in a value of field ' + f)
|
||||
}
|
||||
if (v === '' || /^\s+$/.test(v)) {
|
||||
// ignore empty values
|
||||
continue
|
||||
}
|
||||
// value must be a valid regexp
|
||||
try {
|
||||
// eslint-disable-next-line no-new
|
||||
new RegExp(v)
|
||||
} catch (_err) {
|
||||
throw new Error('Invalid value in field ' + f)
|
||||
}
|
||||
(result[f as keyof ChannelConfigurationOptions] as string[]).push(v)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export {
|
||||
sanitizeChannelConfigurationOptions
|
||||
}
|
88
server/lib/configuration/channel/storage.ts
Normal file
88
server/lib/configuration/channel/storage.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import type { RegisterServerOptions } from '@peertube/peertube-types'
|
||||
import type { ChannelConfiguration, ChannelInfos } from '../../../../shared/lib/types'
|
||||
import { sanitizeChannelConfigurationOptions } from '../../configuration/channel/sanitize'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
|
||||
/**
|
||||
* Get saved configuration options for the given channel.
|
||||
* Can throw an exception.
|
||||
* @param options Peertube server options
|
||||
* @param channelInfos Info from channel from which we want to get infos
|
||||
* @returns Channel configuration data
|
||||
*/
|
||||
async function getChannelConfigurationOptions (
|
||||
options: RegisterServerOptions,
|
||||
channelInfos: ChannelInfos
|
||||
): Promise<ChannelConfiguration> {
|
||||
const logger = options.peertubeHelpers.logger
|
||||
const filePath = _getFilePath(options, channelInfos)
|
||||
if (!fs.existsSync(filePath)) {
|
||||
logger.debug('No stored data for channel, returning default values')
|
||||
return {
|
||||
channel: channelInfos,
|
||||
configuration: {
|
||||
bot: false,
|
||||
bannedJIDs: [],
|
||||
forbiddenWords: []
|
||||
}
|
||||
}
|
||||
}
|
||||
const content = await fs.promises.readFile(filePath, {
|
||||
encoding: 'utf-8'
|
||||
})
|
||||
const sanitized = await sanitizeChannelConfigurationOptions(options, channelInfos, JSON.parse(content))
|
||||
return {
|
||||
channel: channelInfos,
|
||||
configuration: sanitized
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save channel configuration options.
|
||||
* Can throw an exception.
|
||||
* @param options Peertube server options
|
||||
* @param channelConfiguration data to save
|
||||
*/
|
||||
async function storeChannelConfigurationOptions (
|
||||
options: RegisterServerOptions,
|
||||
channelConfiguration: ChannelConfiguration
|
||||
): Promise<void> {
|
||||
const channelInfos = channelConfiguration.channel
|
||||
const filePath = _getFilePath(options, channelInfos)
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
const dir = path.dirname(filePath)
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true })
|
||||
}
|
||||
}
|
||||
|
||||
const jsonContent = JSON.stringify(channelConfiguration.configuration)
|
||||
|
||||
await fs.promises.writeFile(filePath, jsonContent, {
|
||||
encoding: 'utf-8'
|
||||
})
|
||||
}
|
||||
|
||||
function _getFilePath (
|
||||
options: RegisterServerOptions,
|
||||
channelInfos: ChannelInfos
|
||||
): string {
|
||||
const channelId = channelInfos.id
|
||||
// some sanitization, just in case...
|
||||
if (!/^\d+$/.test(channelId.toString())) {
|
||||
throw new Error(`Invalid channelId: ${channelId}`)
|
||||
}
|
||||
|
||||
return path.resolve(
|
||||
options.peertubeHelpers.plugin.getDataDirectoryPath(),
|
||||
'channelConfigurationOptions',
|
||||
channelId.toString() + '.json'
|
||||
)
|
||||
}
|
||||
|
||||
export {
|
||||
getChannelConfigurationOptions,
|
||||
storeChannelConfigurationOptions
|
||||
}
|
Reference in New Issue
Block a user