forked from kaverti/website
118 lines
4.1 KiB
JavaScript
118 lines
4.1 KiB
JavaScript
var md = require('../kaverti_modules/markdown-it')({
|
||
html: false, // Enable HTML tags in source
|
||
xhtmlOut: false, // Use '/' to close single tags (<br />).
|
||
// This is only for full CommonMark compatibility.
|
||
breaks: true, // Convert '\n' in paragraphs into <br>
|
||
langPrefix: 'language-', // CSS language prefix for fenced blocks. Can be
|
||
// useful for external highlighters.
|
||
linkify: true, // Autoconvert URL-like text to links
|
||
image: false,
|
||
|
||
// Enable some language-neutral replacement + quotes beautification
|
||
typographer: true,
|
||
|
||
// Double + single quotes replacement pairs, when typographer enabled,
|
||
// and smartquotes on. Could be either a String or an Array.
|
||
//
|
||
// For example, you can use '«»„“' for Russian, '„“‚‘' for German,
|
||
// and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp).
|
||
quotes: '“”‘’',
|
||
|
||
// Highlighter function. Should return escaped HTML,
|
||
// or '' if the source string is not changed and should be escaped externally.
|
||
// If result starts with <pre... internal wrapper is skipped.
|
||
highlight: function (/*str, lang*/) { return ''; }
|
||
});
|
||
md.disable('image')
|
||
var emoji = require('markdown-it-emoji');
|
||
var twemoji = require('twemoji')
|
||
md.use(emoji);
|
||
md.renderer.rules.emoji = function(token, idx) {
|
||
return twemoji.parse(token[idx].content);
|
||
};
|
||
let createDOMPurify = require('dompurify');
|
||
let { JSDOM } = require('jsdom');
|
||
|
||
let window = new JSDOM('').window;
|
||
let DOMPurify = createDOMPurify(window);
|
||
var escaped_str = require('querystring')
|
||
const Errors = require('../lib/errors')
|
||
let pagination = require('../lib/pagination.js')
|
||
|
||
|
||
module.exports = (sequelize, DataTypes) => {
|
||
let userWall = sequelize.define('userWall', {
|
||
content: {
|
||
type: DataTypes.TEXT,
|
||
set (val) {
|
||
if(!val) {
|
||
throw Errors.sequelizeValidation(sequelize, {
|
||
error: 'content must be a string',
|
||
path: 'content'
|
||
})
|
||
}
|
||
|
||
let rawHTML = md.render(val);
|
||
let cleanHTML = DOMPurify.sanitize(rawHTML);
|
||
let plainText = (new JSDOM(cleanHTML)).window.document.body.textContent;
|
||
|
||
if (!plainText.trim().length) {
|
||
throw Errors.sequelizeValidation(sequelize, {
|
||
error: 'Post content must not be empty',
|
||
path: 'content'
|
||
})
|
||
}
|
||
|
||
|
||
this.setDataValue('content', cleanHTML)
|
||
this.setDataValue('plainText', plainText)
|
||
},
|
||
allowNull: false
|
||
},
|
||
plainText: {
|
||
type: DataTypes.TEXT,
|
||
},
|
||
postNumber: DataTypes.INTEGER,
|
||
replyingToUsername: DataTypes.STRING,
|
||
userId: DataTypes.BIGINT,
|
||
removed: {
|
||
type: DataTypes.BOOLEAN,
|
||
defaultValue: false
|
||
}
|
||
})
|
||
userWall.associate = function (models) {
|
||
userWall.belongsTo(models.User, { as: 'fromUser' })
|
||
}
|
||
userWall.includeOptions = function () {
|
||
let models = sequelize.models
|
||
|
||
return [
|
||
{ model: models.User, as: 'fromUser', attributes: ['username', 'createdAt', 'id', 'color', 'picture'] },
|
||
]
|
||
}
|
||
userWall.prototype.getMeta = function (limit) {
|
||
let Post = sequelize.models.userWall
|
||
let meta = {}
|
||
|
||
let nextId = pagination.getNextIdDesc(userWall, {fromUserId: this.id}, this.Posts)
|
||
|
||
if (nextId === null) {
|
||
meta.nextURL = null
|
||
meta.nextPostsCount = 0
|
||
} else {
|
||
meta.nextURL =
|
||
process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `wall/show/${this.username}?posts=true&limit=${limit}&from=${nextId - 1}`
|
||
|
||
meta.nextPostsCount = pagination.getNextCount(
|
||
Post, this.Posts, limit,
|
||
{fromUserId: this.id},
|
||
true
|
||
)
|
||
}
|
||
|
||
return meta
|
||
}
|
||
|
||
return userWall
|
||
}
|