Skip to content

Commit e92dea5

Browse files
committed
feat: verify turnstile token
1 parent 0ee1b4e commit e92dea5

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

src/graphql/post.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import imageService from '../services/imageService';
3333
import externalInterationService from '../services/externalIntegrationService';
3434
import postService from '../services/postService';
3535
import { checkBlockList } from '../lib/checkBlockList';
36+
import userService from '../services/userService';
37+
import { verifyTurnstileToken } from '../lib/turnstile';
3638

3739
const lruCache = new LRU<string, string[]>({
3840
max: 150,
@@ -125,6 +127,7 @@ export const typeDef = gql`
125127
thumbnail: String
126128
meta: JSON
127129
series_id: ID
130+
token: String
128131
): Post
129132
editPost(
130133
id: ID!
@@ -138,6 +141,7 @@ export const typeDef = gql`
138141
meta: JSON
139142
is_private: Boolean
140143
series_id: ID
144+
token: String
141145
): Post
142146
createPostHistory(
143147
post_id: ID!
@@ -173,6 +177,7 @@ type WritePostArgs = {
173177
meta: any;
174178
series_id?: string;
175179
is_private: boolean;
180+
token: string | null;
176181
};
177182

178183
type CreatePostHistoryArgs = {
@@ -181,6 +186,7 @@ type CreatePostHistoryArgs = {
181186
body: string;
182187
is_markdown: boolean;
183188
};
189+
184190
type EditPostArgs = WritePostArgs & {
185191
id: string;
186192
};
@@ -730,11 +736,30 @@ export const resolvers: IResolvers<any, ApolloContext> = {
730736
}
731737
}
732738

739+
// check block list
733740
const isBlockList = await checkBlockList(ctx.user_id, user?.username);
734741
if (isBlockList) {
735742
post.is_private = true;
736743
}
737744

745+
// check bot
746+
if (!data.is_private || !data.is_temp) {
747+
const isTrustUser = await userService.checkTrust(ctx.user_id);
748+
if (!isTrustUser && !data.token) {
749+
throw new ApolloError(
750+
'A Turnstile token is required for users who are not trusted',
751+
'NO_PERMISSION'
752+
);
753+
}
754+
755+
if (!isTrustUser) {
756+
const isVerified = await verifyTurnstileToken(data.token!);
757+
if (!isVerified) {
758+
post.is_private = true;
759+
}
760+
}
761+
}
762+
738763
let processedUrlSlug = escapeForUrl(data.url_slug);
739764
const urlSlugDuplicate = await postRepo.findOne({
740765
where: {
@@ -878,6 +903,7 @@ export const resolvers: IResolvers<any, ApolloContext> = {
878903
url_slug,
879904
tags,
880905
is_private,
906+
token,
881907
} = args as EditPostArgs;
882908
const postRepo = getRepository(Post);
883909
const seriesRepo = getRepository(Series);
@@ -1027,6 +1053,24 @@ export const resolvers: IResolvers<any, ApolloContext> = {
10271053
post.is_private = true;
10281054
}
10291055

1056+
// check bot
1057+
if (!is_private || !is_temp) {
1058+
const isTrustUser = await userService.checkTrust(ctx.user_id);
1059+
if (!isTrustUser && !token) {
1060+
throw new ApolloError(
1061+
'A Turnstile token is required for users who are not trusted',
1062+
'NO_PERMISSION'
1063+
);
1064+
}
1065+
1066+
if (!isTrustUser) {
1067+
const isVerified = await verifyTurnstileToken(token!);
1068+
if (!isVerified) {
1069+
post.is_private = true;
1070+
}
1071+
}
1072+
}
1073+
10301074
const tagsData = await Promise.all(tags.map(Tag.findOrCreate));
10311075
await Promise.all([PostsTags.syncPostTags(post.id, tagsData), postRepo.save(post)]);
10321076

src/lib/turnstile.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import axios from 'axios';
2+
3+
const TURNSTILE_SECRET_KEY = process.env.TURNSTILE_SECRET_KEY;
4+
5+
console.log('verifyTurnstileToken', TURNSTILE_SECRET_KEY);
6+
const VERIFY_URL = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
7+
8+
export async function verifyTurnstileToken(token: string): Promise<boolean> {
9+
try {
10+
const res = await axios.post<{ success: boolean }>(VERIFY_URL, {
11+
secret: TURNSTILE_SECRET_KEY,
12+
response: token,
13+
});
14+
15+
console.log('toklen', res);
16+
return res.data.success;
17+
} catch (error) {
18+
console.log('verifyTurnstileToken error', error);
19+
return false;
20+
}
21+
}

0 commit comments

Comments
 (0)