fix: friend enforcement

This commit is contained in:
cha0s 2020-12-11 12:10:35 -06:00
parent bb666f7353
commit 6687884604
5 changed files with 41 additions and 18 deletions

View File

@ -19,13 +19,13 @@ export default function Channels(props) {
{( {(
channels channels
.sort(({name: l}, {name: r}) => (l < r ? -1 : 1)) .sort(({name: l}, {name: r}) => (l < r ? -1 : 1))
.map(({actions, name}) => ( .map((channel) => (
<Channel <Channel
key={name} key={channel.name}
actions={actions} href={`/chat${type}${channel.name}`}
href={`/chat${type}${name}`}
name={name}
type={type} type={type}
// eslint-disable-next-line react/jsx-props-no-spreading
{...channel}
/> />
)) ))
)} )}

View File

@ -26,6 +26,7 @@ export default function ChatLeftFriendsPendingIncoming() {
['👎', 'Deny friend request', () => dispatch(submitRemoveFriend(adderId))], ['👎', 'Deny friend request', () => dispatch(submitRemoveFriend(adderId))],
['👍', 'Confirm friend request', () => dispatch(submitConfirmFriend(adderId))], ['👍', 'Confirm friend request', () => dispatch(submitConfirmFriend(adderId))],
], ],
href: '',
})); }));
return ( return (
<div <div

View File

@ -24,6 +24,7 @@ export default function ChatLeftFriendsPendingOutgoing() {
actions: [ actions: [
['×', 'Cancel friend request', () => dispatch(submitRemoveFriend(addeeId))], ['×', 'Cancel friend request', () => dispatch(submitRemoveFriend(addeeId))],
], ],
href: '',
})); }));
return ( return (
<div <div

View File

@ -104,7 +104,11 @@ export default function ChatRightUsers() {
key={id} key={id}
actions={userActions} actions={userActions}
href={( href={(
(hasFriendship && userId !== id) (
hasFriendship
&& 'active' === friendship[index].status
&& userId !== id
)
? `/chat/u/${username}` ? `/chat/u/${username}`
: null : null
)} )}

View File

@ -1,6 +1,6 @@
import {v4 as uuidv4} from 'uuid'; import {v4 as uuidv4} from 'uuid';
import {ModelMap} from '@latus/db'; import {ModelMap, Op} from '@latus/db';
import {createLimiter} from '@latus/governor'; import {createLimiter} from '@latus/governor';
import {ValidationError} from '@latus/socket'; import {ValidationError} from '@latus/socket';
import {channelIsAnonymous, renderChannel, validateChannel} from '@reddichat/core'; import {channelIsAnonymous, renderChannel, validateChannel} from '@reddichat/core';
@ -21,15 +21,6 @@ export default (latus) => class MessageServer extends Message(latus) {
const {User} = ModelMap(latus); const {User} = ModelMap(latus);
const {channel, message} = data; const {channel, message} = data;
const {name, type} = channel; const {name, type} = channel;
const isAnonymous = channelIsAnonymous(channel);
const owner = isAnonymous ? 0 : req.userId;
const rendered = renderChannel(channel);
const serverChannel = 'r' === type
? rendered
: `/u/${[name, req.user.redditUsername].sort().join('$')}`;
const timestamp = Date.now();
const uuid = uuidv4();
const key = `${serverChannel}:messages:${uuid}`;
let destinations = []; let destinations = [];
if ('u' === type) { if ('u' === type) {
const other = await User.findOne({where: {redditUsername: name}}); const other = await User.findOne({where: {redditUsername: name}});
@ -51,6 +42,10 @@ export default (latus) => class MessageServer extends Message(latus) {
channel, channel,
]; ];
} }
const isAnonymous = channelIsAnonymous(channel);
const owner = isAnonymous ? 0 : req.userId;
const timestamp = Date.now();
const uuid = uuidv4();
destinations.forEach((room, i) => ( destinations.forEach((room, i) => (
socket socket
.to(renderChannel(room)) .to(renderChannel(room))
@ -68,6 +63,11 @@ export default (latus) => class MessageServer extends Message(latus) {
}]) }])
)); ));
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const rendered = renderChannel(channel);
const serverChannel = 'r' === type
? rendered
: `/u/${[name, req.user.redditUsername].sort().join('$')}`;
const key = `${serverChannel}:messages:${uuid}`;
pubClient pubClient
.multi() .multi()
.set(key, JSON.stringify({ .set(key, JSON.stringify({
@ -83,12 +83,29 @@ export default (latus) => class MessageServer extends Message(latus) {
} }
static async validate({data: {channel, message}}, socket) { static async validate({data: {channel, message}}, socket) {
const {req} = socket;
await this.characterLimiter.consume(socket.id, message.length); await this.characterLimiter.consume(socket.id, message.length);
if (!validateChannel(channel)) { if (!validateChannel(channel)) {
throw new ValidationError({code: 400, reason: 'Malformed channel'}); throw new ValidationError({code: 400, reason: 'invalid channel'});
} }
if (message.length > 512) { if (message.length > 512) {
throw new ValidationError({code: 400, reason: 'Message larger than 512 bytes'}); throw new ValidationError({code: 400, reason: '> 512 bytes'});
}
const {Friendship, User} = ModelMap(latus);
const {name, type} = channel;
if ('u' === type) {
const other = await User.findOne({where: {redditUsername: name}});
const friendship = await Friendship.findOne({
where: {
[Op.or]: [
{[Op.and]: [{addeeId: req.userId}, {adderId: other.id}]},
{[Op.and]: [{addeeId: other.id}, {adderId: req.userId}]},
],
},
});
if (!friendship || 'active' !== friendship.status) {
throw new ValidationError({code: 403, reason: 'not friends'});
}
} }
} }