[fedi] comment/instance/user moderation
This commit is contained in:
@@ -96,7 +96,7 @@ const eventController = {
|
||||
{ model: Tag, attributes: ['tag', 'weigth'], through: { attributes: [] } },
|
||||
{ model: User, attributes: ['username'] },
|
||||
{ model: Place, attributes: ['name', 'address'] },
|
||||
Comment
|
||||
{ model: Comment, where: !is_admin && { hidden: false }, required: false }
|
||||
],
|
||||
order: [ [Comment, 'id', 'DESC'] ]
|
||||
})
|
||||
|
||||
27
server/api/controller/fed_user.js
Normal file
27
server/api/controller/fed_user.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const { fed_users: FedUsers, comment: Comment } = require('../models')
|
||||
|
||||
const fedUserController = {
|
||||
async toggleBlock (req, res) {
|
||||
const user_id = req.body.user_id
|
||||
const user = await FedUsers.findByPk(user_id)
|
||||
user.update({ blocked: !user.blocked })
|
||||
res.json(user)
|
||||
},
|
||||
|
||||
async hideComment (req, res) {
|
||||
const comment_id = req.params.comment_id
|
||||
const hidden = req.body.hidden
|
||||
const comment = await Comment.findByPk(comment_id)
|
||||
await comment.update({ hidden })
|
||||
res.json(comment)
|
||||
},
|
||||
|
||||
async removeComment (req, res) {
|
||||
const comment_id = req.params.comment_id
|
||||
const comment = await Comment.findByPk(comment_id)
|
||||
await comment.destroy()
|
||||
res.sendStatus(200)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = fedUserController
|
||||
@@ -1,5 +1,5 @@
|
||||
const Sequelize = require('sequelize')
|
||||
const { fed_users: FedUsers, instances: Instances } = require('../models')
|
||||
const { fed_users: FedUsers, instances: Instances, comment: Comment } = require('../models')
|
||||
|
||||
const instancesController = {
|
||||
async getAll (req, res) {
|
||||
@@ -12,6 +12,15 @@ const instancesController = {
|
||||
})
|
||||
return res.json(instances)
|
||||
},
|
||||
|
||||
/**
|
||||
* get instance users
|
||||
*/
|
||||
async get (req, res) {
|
||||
const fedi_users = await FedUsers.findAll({ where: { instanceDomain: req.params.instance_domain }, include: [Comment] })
|
||||
return res.json(fedi_users)
|
||||
},
|
||||
|
||||
async toggleBlock (req, res) {
|
||||
const instance = await Instances.findByPk(req.body.instance)
|
||||
if (!instance) { return res.status(404).send('Not found') }
|
||||
|
||||
@@ -9,6 +9,7 @@ const exportController = require('./controller/export')
|
||||
const userController = require('./controller/user')
|
||||
const settingsController = require('./controller/settings')
|
||||
const instancesController = require('./controller/instances')
|
||||
const fedUserController = require('./controller/fed_user')
|
||||
|
||||
const storage = require('./storage')
|
||||
const upload = multer({ storage })
|
||||
@@ -84,7 +85,11 @@ api.get('/export/:type', exportController.export)
|
||||
api.get('/event/:month/:year', eventController.getAll)
|
||||
|
||||
api.get('/instances', isAdmin, instancesController.getAll)
|
||||
api.get('/instances/:instance_domain', isAdmin, instancesController.get)
|
||||
api.post('/instances/toggle_block', isAdmin, instancesController.toggleBlock)
|
||||
api.post('/instances/toggle_user_block', isAdmin, fedUserController.toggleBlock)
|
||||
api.post('/comments/:comment_id', isAdmin, fedUserController.hideComment)
|
||||
api.delete('/comments/:comment_id', isAdmin, fedUserController.removeComment)
|
||||
|
||||
// Handle 404
|
||||
api.use((req, res) => {
|
||||
|
||||
@@ -6,10 +6,21 @@ module.exports = (sequelize, DataTypes) => {
|
||||
index: true,
|
||||
unique: true
|
||||
},
|
||||
hidden: DataTypes.BOOLEAN,
|
||||
fedUserApId: {
|
||||
type: DataTypes.STRING,
|
||||
references: {
|
||||
model: 'fed_users',
|
||||
key: 'ap_id'
|
||||
},
|
||||
onUpdate: 'CASCADE',
|
||||
onDelete: 'CASCADE'
|
||||
},
|
||||
data: DataTypes.JSON
|
||||
}, {})
|
||||
comment.associate = function (models) {
|
||||
comment.belongsTo(models.event)
|
||||
comment.belongsTo(models.fed_users)
|
||||
}
|
||||
return comment
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@ module.exports = (sequelize, DataTypes) => {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true
|
||||
},
|
||||
blocked: DataTypes.BOOLEAN,
|
||||
object: DataTypes.JSON
|
||||
}, {})
|
||||
fed_users.associate = function (models) {
|
||||
fed_users.belongsTo(models.instances)
|
||||
fed_users.belongsToMany(models.user, { through: 'user_followers', as: 'followers' })
|
||||
fed_users.hasMany(models.comment, { foreignKey: 'fedUserApId' })
|
||||
}
|
||||
return fed_users
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ module.exports = {
|
||||
|
||||
await Comment.create({
|
||||
activitypub_id: body.object.id,
|
||||
fedUserApId: req.body.actor,
|
||||
data: body.object,
|
||||
eventId: event.id
|
||||
})
|
||||
|
||||
@@ -137,7 +137,7 @@ const Helpers = {
|
||||
if (!fedi_user.instances) {
|
||||
fedi_user.setInstance(instance)
|
||||
}
|
||||
return fedi_user.object
|
||||
return fedi_user
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ const Helpers = {
|
||||
})
|
||||
|
||||
if (fedi_user) {
|
||||
await FedUsers.create({ ap_id: URL, object: fedi_user })
|
||||
fedi_user = await FedUsers.create({ ap_id: URL, object: fedi_user })
|
||||
}
|
||||
return fedi_user
|
||||
},
|
||||
@@ -194,6 +194,10 @@ const Helpers = {
|
||||
|
||||
let user = await Helpers.getActor(req.body.actor, instance)
|
||||
if (!user) { return res.status(401).send('Actor not found') }
|
||||
if (user.blocked) {
|
||||
debug('User %s blocked', user.ap_id)
|
||||
return res.status(401).send('User blocked')
|
||||
}
|
||||
|
||||
// little hack -> https://github.com/joyent/node-http-signature/pull/83
|
||||
req.headers.authorization = 'Signature ' + req.headers.signature
|
||||
@@ -204,12 +208,12 @@ const Helpers = {
|
||||
// https://github.com/joyent/node-http-signature/issues/87
|
||||
req.url = '/federation' + req.url
|
||||
const parsed = httpSignature.parseRequest(req)
|
||||
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) { return next() }
|
||||
if (httpSignature.verifySignature(parsed, user.object.publicKey.publicKeyPem)) { return next() }
|
||||
|
||||
// signature not valid, try without cache
|
||||
user = await Helpers.getActor(req.body.actor, instance, true)
|
||||
if (!user) { return res.status(401).send('Actor not found') }
|
||||
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) { return next() }
|
||||
if (httpSignature.verifySignature(parsed, user.object.publicKey.publicKeyPem)) { return next() }
|
||||
|
||||
// still not valid
|
||||
debug('Invalid signature from user %s', req.body.actor)
|
||||
|
||||
17
server/migrations/20191111152540-comment_feduserId.js
Normal file
17
server/migrations/20191111152540-comment_feduserId.js
Normal file
@@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
return queryInterface.addColumn('comments', 'fedUserApId', {
|
||||
type: Sequelize.STRING,
|
||||
references: {
|
||||
model: 'fed_users',
|
||||
key: 'ap_id'
|
||||
},
|
||||
onUpdate: 'CASCADE',
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
},
|
||||
|
||||
down: (queryInterface, Sequelize) => {
|
||||
return queryInterface.removeColumn('comments', 'fedUserApId')
|
||||
}
|
||||
}
|
||||
11
server/migrations/20191111195639-user_blocked.js
Normal file
11
server/migrations/20191111195639-user_blocked.js
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
return queryInterface.addColumn('fed_users', 'blocked', { type: Sequelize.BOOLEAN })
|
||||
},
|
||||
|
||||
down: (queryInterface, Sequelize) => {
|
||||
return queryInterface.removeColumn('fed_users', 'blocked', { type: Sequelize.BOOLEAN })
|
||||
}
|
||||
}
|
||||
12
server/migrations/20191111234434-hide_comment.js
Normal file
12
server/migrations/20191111234434-hide_comment.js
Normal file
@@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
return queryInterface.addColumn('comments', 'hidden', {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false
|
||||
})
|
||||
},
|
||||
|
||||
down: (queryInterface, Sequelize) => {
|
||||
return queryInterface.removeColumn('comments', 'hidden')
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ router.use(spamFilter)
|
||||
|
||||
// serve favicon and static content
|
||||
router.use('/favicon.ico', express.static(path.resolve(config.favicon || './assets/favicon.ico')))
|
||||
router.use('/logo.png', express.static('./static/gancio.png'))
|
||||
router.use('/media/', express.static(config.upload_path))
|
||||
|
||||
// get instance settings
|
||||
|
||||
Reference in New Issue
Block a user