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 {parseChannel} from '@reddichat/core';
import {createLimiter} from '@latus/governor/client'; 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 {v4 as uuidv4} from 'uuid';
import { import {
@ -34,7 +34,16 @@ export default ({config: {'%socket': socket}}) => {
[submitJoin]: async ({dispatch}, {payload}) => { [submitJoin]: async ({dispatch}, {payload}) => {
const {channel} = payload; const {channel} = payload;
try { 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; const realChannel = canonical ? parseChannel(canonical) : channel;
dispatch(join({ dispatch(join({
channel: realChannel, channel: realChannel,

View File

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

View File

@ -14,6 +14,14 @@ export default (latus) => class JoinServer extends Join(latus) {
const {User} = ModelMap(latus); const {User} = ModelMap(latus);
const chat = await ensureCanonical(latus, channel); const chat = await ensureCanonical(latus, channel);
const canonical = parseChannel(chat.name); const canonical = parseChannel(chat.name);
if (req.user && await req.user.isBannedFrom(canonical)) {
return {
isBanned: true,
messages: {},
users: [],
usernames: {},
};
}
await joinChannel(latus, canonical, socket); await joinChannel(latus, canonical, socket);
const state = await channelState(req, latus, canonical); const state = await channelState(req, latus, canonical);
const usernames = Object.fromEntries(await Promise.all( 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, 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'}); throw new ValidationError({code: 403, reason: 'not friends'});
} }
} }
if (user && await user.isBannedFrom(channel)) {
throw new ValidationError({code: 403, reason: 'unauthorized'});
}
if (distinction && !user) { if (distinction && !user) {
throw new ValidationError({code: 403, reason: 'unauthorized'}); 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) => { 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() { async blocks() {
return (await this.getBlocks()).map(({blocked}) => blocked); 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) { async isModOf(channel) {
return -1 !== (await this.modOf).indexOf(renderChannel(channel)); return -1 !== (await this.modOf).indexOf(renderChannel(channel));
} }