You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wiki/server/modules/comments/default/comment.js

185 lines
5.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

const md = require('markdown-it')
const mdEmoji = require('markdown-it-emoji')
const { JSDOM } = require('jsdom')
const createDOMPurify = require('dompurify')
const _ = require('lodash')
const { AkismetClient } = require('akismet-api')
const moment = require('moment')
/* global WIKI */
const window = new JSDOM('').window
const DOMPurify = createDOMPurify(window)
let akismetClient = null
const mkdown = md({
html: false,
breaks: true,
linkify: true,
highlight(str, lang) {
return `<pre><code class="language-${lang}">${_.escape(str)}</code></pre>`
}
})
mkdown.use(mdEmoji)
// ------------------------------------
// Default Comment Provider
// ------------------------------------
module.exports = {
/**
* Init
*/
async init (config) {
WIKI.logger.info('(COMMENTS/DEFAULT) Initializing...')
if (WIKI.data.commentProvider.config.akismet && WIKI.data.commentProvider.config.akismet.length > 2) {
akismetClient = new AkismetClient({
key: WIKI.data.commentProvider.config.akismet,
blog: WIKI.config.host,
lang: WIKI.config.lang.namespacing ? WIKI.config.lang.namespaces.join(', ') : WIKI.config.lang.code,
charset: 'UTF-8'
})
try {
const isValid = await akismetClient.verifyKey()
if (!isValid) {
akismetClient = null
WIKI.logger.warn('(COMMENTS/DEFAULT) Akismet Key is invalid! [ DISABLED ]')
} else {
WIKI.logger.info('(COMMENTS/DEFAULT) Akismet key is valid. [ OK ]')
}
} catch (err) {
akismetClient = null
WIKI.logger.warn('(COMMENTS/DEFAULT) Unable to verify Akismet Key: ' + err.message)
}
} else {
akismetClient = null
}
WIKI.logger.info('(COMMENTS/DEFAULT) Initialization completed.')
},
/**
* Create New Comment
*/
async create ({ page, replyTo, content, user }) {
// -> Build New Comment
const newComment = {
content,
render: DOMPurify.sanitize(mkdown.render(content)),
replyTo,
pageId: page.id,
authorId: user.id,
name: user.name,
email: user.email,
ip: user.ip
}
// -> Check for Spam with Akismet
if (akismetClient) {
let userRole = 'user'
if (user.groups.indexOf(1) >= 0) {
userRole = 'administrator'
} else if (user.groups.indexOf(2) >= 0) {
userRole = 'guest'
}
let isSpam = false
try {
isSpam = await akismetClient.checkSpam({
ip: user.ip,
useragent: user.agentagent,
content,
name: user.name,
email: user.email,
permalink: `${WIKI.config.host}/${page.localeCode}/${page.path}`,
permalinkDate: page.updatedAt,
type: (replyTo > 0) ? 'reply' : 'comment',
role: userRole
})
} catch (err) {
WIKI.logger.warn('Akismet Comment Validation: [ FAILED ]')
WIKI.logger.warn(err)
}
if (isSpam) {
throw new Error('Comment was rejected because it is marked as spam.')
}
}
// -> Check for minimum delay between posts
if (WIKI.data.commentProvider.config.minDelay > 0) {
const lastComment = await WIKI.models.comments.query().select('updatedAt').findOne('authorId', user.id).orderBy('updatedAt', 'desc')
if (lastComment && moment().subtract(WIKI.data.commentProvider.config.minDelay, 'seconds').isBefore(lastComment.updatedAt)) {
throw new Error('Your administrator has set a time limit before you can post another comment. Try again later.')
}
}
// -> Save Comment to DB
const cm = await WIKI.models.comments.query().insert(newComment)
// -> Return Comment ID
return cm.id
},
/**
* Update an existing comment
*/
async update ({ id, content, user }) {
const renderedContent = DOMPurify.sanitize(mkdown.render(content))
await WIKI.models.comments.query().findById(id).patch({
content,
render: renderedContent
})
return renderedContent
},
/**
* Delete an existing comment by ID
*/
async remove ({ id, page, Comment, content,authorId, user,config}) {
await WIKI.mail.send({
template: 'coment',
to: page.authorEmail,
subject: `Коментарий удален`,
data: {
preheadertext: `ВАЖНО`,
title: user.name + ` удалил коментарий к статье: ` + page.title,
content: `Вы получили это сообщение потому что являетесь автором этой статьи`,
buttonLink: WIKI.config.host+`/`+page.path,
buttonText: 'Перейти к странице',
},
text: `Молодец ты нашел этот текст сообщи о своей находке и ни чего не произойдет `
})
return WIKI.models.comments.query().findById(id).delete()
},
/**
* Get the page ID from a comment ID
*/
async getPageIdFromCommentId (id) {
const result = await WIKI.models.comments.query().select('pageId').findById(id)
return (result) ? result.pageId : false
},
/**
* Get a comment by ID
*/
async getCommentById (id) {
return WIKI.models.comments.query().findById(id)
},
/**
* Get the total comments count for a page ID
*/
async count (pageId) {
const result = await WIKI.models.comments.query().count('* as total').where('pageId', pageId).first()
return _.toSafeInteger(result.total)
}
}