Skip to content
This repository was archived by the owner on Sep 7, 2020. It is now read-only.

Commit be13385

Browse files
committed
fix: check for allowed channels before joining
1 parent ee81cdf commit be13385

File tree

2 files changed

+103
-63
lines changed

2 files changed

+103
-63
lines changed

src/Chat/SlashCommands.tsx

+70-63
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import {
88
VerifyTokenQueryResult,
99
VerifyTokenVariables,
1010
} from '../graphql/verifyTokenQuery'
11+
import * as TE from 'fp-ts/lib/TaskEither'
12+
import { verifyToken } from './Twilio/api'
13+
import { pipe } from 'fp-ts/lib/pipeable'
1114

1215
export enum SlashCommand {
1316
HELP = 'help',
@@ -43,32 +46,70 @@ export const SlashCommandHandler = ({
4346
onChangeNick: (nick: string) => void
4447
token: string
4548
}) => (cmd: SlashCommand, arg?: string) => {
49+
const showMessage = (message: string | React.ReactNode) =>
50+
updateMessages(prevMessages => ({
51+
...prevMessages,
52+
messages: [
53+
...prevMessages.messages,
54+
{
55+
sid: v4(),
56+
status: {
57+
message,
58+
timestamp: new Date(),
59+
},
60+
},
61+
],
62+
}))
63+
4664
switch (cmd) {
4765
case SlashCommand.HELP:
48-
updateMessages(prevMessages => ({
49-
...prevMessages,
50-
messages: [
51-
...prevMessages.messages,
52-
{
53-
sid: v4(),
54-
status: {
55-
message: (
56-
<p>
57-
/me: show information about you
58-
<br />
59-
/join <code>&lt;channel&gt;</code>: join another channel
60-
<br />
61-
/nick <code>&lt;nickname&gt;</code>: set your nickname
62-
</p>
63-
),
64-
timestamp: new Date(),
65-
},
66-
},
67-
],
68-
}))
66+
showMessage(
67+
<p>
68+
/me: show information about you
69+
<br />
70+
/join <code>&lt;channel&gt;</code>: join another channel
71+
<br />
72+
/nick <code>&lt;nickname&gt;</code>: set your nickname
73+
</p>,
74+
)
6975
break
7076
case SlashCommand.JOIN:
71-
onSwitchChannel(arg as string)
77+
console.log(token)
78+
if (!arg || !arg.length) {
79+
showMessage(
80+
<p>
81+
You must provide a channel name, e.g.:{' '}
82+
<code>/join some-channel</code>!
83+
</p>,
84+
)
85+
return
86+
}
87+
showMessage(
88+
<p>
89+
Joining <code>{arg}</code>...
90+
</p>,
91+
)
92+
pipe(
93+
verifyToken({ apollo, token }),
94+
TE.map(({ contexts }) => {
95+
if (!contexts.includes(arg)) {
96+
showMessage(
97+
<p>
98+
You are not allowed to join the channel <code>{arg}</code>.
99+
<br />
100+
These are the cannels join can join: {contexts.join(', ')}
101+
</p>,
102+
)
103+
return
104+
}
105+
onSwitchChannel(arg)
106+
}),
107+
TE.mapLeft(err => {
108+
showMessage(`Failed to verify token: ${err.message}`)
109+
}),
110+
)().catch(err => {
111+
console.error(err)
112+
})
72113
break
73114
case SlashCommand.NICK:
74115
onChangeNick(arg as string)
@@ -81,52 +122,18 @@ export const SlashCommandHandler = ({
81122
})
82123
.then(({ data }) => {
83124
if (!data) {
84-
updateMessages(prevMessages => ({
85-
...prevMessages,
86-
messages: [
87-
...prevMessages.messages,
88-
{
89-
sid: v4(),
90-
status: {
91-
message: `Failed to verify token!`,
92-
timestamp: new Date(),
93-
},
94-
},
95-
],
96-
}))
125+
showMessage(`Failed to verify token!`)
97126
} else {
98127
const { identity, contexts } = data.verifyToken
99-
updateMessages(prevMessages => ({
100-
...prevMessages,
101-
messages: [
102-
...prevMessages.messages,
103-
{
104-
sid: v4(),
105-
status: {
106-
message: `Hey ${identity}, you are allowed to access these channels: ${contexts.join(
107-
',',
108-
)}.`,
109-
timestamp: new Date(),
110-
},
111-
},
112-
],
113-
}))
128+
showMessage(
129+
`Hey ${identity}, you are allowed to access these channels: ${contexts.join(
130+
',',
131+
)}.`,
132+
)
114133
}
115134
})
116135
.catch(err => {
117-
updateMessages(prevMessages => ({
118-
...prevMessages,
119-
messages: [
120-
...prevMessages.messages,
121-
{
122-
sid: v4(),
123-
status: {
124-
message: `Failed to verify token: ${err.message}`,
125-
timestamp: new Date(),
126-
},
127-
},
128-
],
129-
}))
136+
showMessage(`Failed to verify token: ${err.message}`)
130137
})
131138
}
132139
}

src/Chat/Twilio/api.ts

+33
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ import { pipe } from 'fp-ts/lib/pipeable'
1313
import { Option, fromNullable } from 'fp-ts/lib/Option'
1414
import { Paginator } from 'twilio-chat/lib/interfaces/paginator'
1515
import { getOrElse } from '../../fp-ts.util'
16+
import {
17+
VerifyTokenQueryResult,
18+
VerifyTokenVariables,
19+
verifyTokenQuery,
20+
} from '../../graphql/verifyTokenQuery'
1621

1722
type ErrorInfo = {
1823
type: string
@@ -49,6 +54,34 @@ const createChatToken = ({
4954
}),
5055
)
5156

57+
export const verifyToken = ({
58+
apollo,
59+
token,
60+
}: {
61+
token: string
62+
apollo: ApolloClient<NormalizedCacheObject>
63+
}) =>
64+
tryCatch<ErrorInfo, { identity: string; contexts: string[] }>(
65+
async () =>
66+
apollo
67+
.query<VerifyTokenQueryResult, VerifyTokenVariables>({
68+
query: verifyTokenQuery,
69+
variables: { token },
70+
})
71+
.then(({ data }) => {
72+
if (!data) {
73+
throw new Error('No response received!')
74+
} else {
75+
const { identity, contexts } = data.verifyToken
76+
return { identity, contexts }
77+
}
78+
}),
79+
reason => ({
80+
type: 'TokenError',
81+
message: `Failed to verify token: ${(reason as Error).message}`,
82+
}),
83+
)
84+
5285
const createClient = (chatToken: string) =>
5386
tryCatch<ErrorInfo, Client>(
5487
async () => Client.create(chatToken),

0 commit comments

Comments
 (0)