feat: chat ban enforcement

This commit is contained in:
cha0s 2020-12-13 12:15:21 -06:00
parent 9ad7952268
commit 9d2438167c
6 changed files with 44 additions and 4 deletions

View File

@ -1,6 +1,6 @@
import {parseChannel} from '@reddichat/core';
import {createLimiter} from '@latus/governor/client';
import {push} from 'connected-react-router';
import {push, replace} from 'connected-react-router';
import {v4 as uuidv4} from 'uuid';
import {
@ -34,7 +34,16 @@ export default ({config: {'%socket': socket}}) => {
[submitJoin]: async ({dispatch}, {payload}) => {
const {channel} = payload;
try {
const {canonical, messages, users} = await socket.send(['Join', payload]);
const {
canonical,
isBanned,
messages,
users,
} = await socket.send(['Join', payload]);
if (isBanned) {
dispatch(replace('/chat'));
return;
}
const realChannel = canonical ? parseChannel(canonical) : channel;
dispatch(join({
channel: realChannel,

View File

@ -49,6 +49,10 @@ export default {
res.redirect(`/chat${chat.name}`);
return;
}
if (req.user && await req.user.isBannedFrom(chat)) {
res.redirect('/chat');
return;
}
}
catch (error) {
res.redirect('/chat');

View File

@ -14,6 +14,14 @@ export default (latus) => class JoinServer extends Join(latus) {
const {User} = ModelMap(latus);
const chat = await ensureCanonical(latus, channel);
const canonical = parseChannel(chat.name);
if (req.user && await req.user.isBannedFrom(canonical)) {
return {
isBanned: true,
messages: {},
users: [],
usernames: {},
};
}
await joinChannel(latus, canonical, socket);
const state = await channelState(req, latus, canonical);
const usernames = Object.fromEntries(await Promise.all(
@ -22,7 +30,11 @@ export default (latus) => class JoinServer extends Join(latus) {
0 === id ? 'anonymous' : (await User.findByPk(id)).redditUsername,
]),
));
return {...state, usernames, ...(chat.name !== channel.name ? {canonical: chat.name} : {})};
return {
...state,
usernames,
...(chat.name !== channel.name ? {canonical: chat.name} : {}),
};
}
};

View File

@ -108,6 +108,9 @@ export default (latus) => class MessageServer extends Message(latus) {
throw new ValidationError({code: 403, reason: 'not friends'});
}
}
if (user && await user.isBannedFrom(channel)) {
throw new ValidationError({code: 403, reason: 'unauthorized'});
}
if (distinction && !user) {
throw new ValidationError({code: 403, reason: 'unauthorized'});
}

View File

@ -78,7 +78,9 @@ export const channelsToHydrate = async (req, latus) => {
}),
))),
);
return Array.from((new Set(channels.map(renderChannel))).values()).map(parseChannel);
return Promise.all(Array.from((new Set(channels.map(renderChannel))).values())
.map(parseChannel)
.filter((channel) => !user.isBannedFrom(channel)));
};
export const chatUserIds = async (req, latus) => {

View File

@ -12,6 +12,12 @@ export default (User, latus) => class UserReddichat extends User {
};
}
get bannedFrom() {
return this.getBannedFrom().then((chatRooms) => (
Promise.all(chatRooms.map(async ({name}) => name))
));
}
async blocks() {
return (await this.getBlocks()).map(({blocked}) => blocked);
}
@ -39,6 +45,10 @@ export default (User, latus) => class UserReddichat extends User {
));
}
async isBannedFrom(channel) {
return -1 !== (await this.bannedFrom).indexOf(renderChannel(channel));
}
async isModOf(channel) {
return -1 !== (await this.modOf).indexOf(renderChannel(channel));
}