Skip to content

Commit 4cb9013

Browse files
committed
Fix captcha
1 parent 717de73 commit 4cb9013

3 files changed

Lines changed: 60 additions & 8 deletions

File tree

web/app/pages/search-messages/index.vue

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ interface Turnstile {
2828
"error-callback"?: (error: string) => void;
2929
},
3030
): string | null | undefined;
31+
reset(widgetId?: string): void;
32+
remove(widgetId?: string): void;
3133
}
3234
3335
definePageMeta({
@@ -63,6 +65,8 @@ const formQuery = ref("");
6365
const messages = ref<EntitiesMessage[]>([]);
6466
const totalMessages = ref(0);
6567
const selectedIds = ref<string[]>([]);
68+
let turnstileWidgetId: string | null = null;
69+
let captchaPromise: Promise<string> | null = null;
6670
6771
const page = ref(1);
6872
const itemsPerPage = ref(100);
@@ -123,23 +127,51 @@ const messageStatusSelectItems = [
123127
];
124128
125129
function getCaptcha(): Promise<string> {
126-
return new Promise<string>((resolve, reject) => {
130+
if (captchaPromise) {
131+
return captchaPromise;
132+
}
133+
134+
captchaPromise = new Promise<string>((resolve, reject) => {
127135
const turnstile = (window as unknown as { turnstile?: Turnstile })
128136
.turnstile;
129137
if (!turnstile) {
130138
resolve("");
131139
return;
132140
}
141+
142+
const resetPromise = () => {
143+
captchaPromise = null;
144+
};
145+
133146
turnstile.ready(() => {
134-
turnstile.render("#cloudflare-turnstile", {
135-
sitekey: (config.public as Record<string, string>)
136-
.cloudflareTurnstileSiteKey!,
137-
action: "search_messages",
138-
callback: (token) => resolve(token),
139-
"error-callback": (error: string) => reject(error),
140-
});
147+
const complete = (token: string) => {
148+
resetPromise();
149+
resolve(token);
150+
};
151+
const fail = (error: string) => {
152+
resetPromise();
153+
reject(error);
154+
};
155+
156+
if (turnstileWidgetId) {
157+
turnstile.reset(turnstileWidgetId);
158+
return;
159+
}
160+
161+
turnstileWidgetId =
162+
turnstile.render("#cloudflare-turnstile", {
163+
sitekey: (config.public as Record<string, string>)
164+
.cloudflareTurnstileSiteKey!,
165+
action: "search_messages",
166+
callback: complete,
167+
"error-callback": fail,
168+
}) ?? null;
141169
});
142170
});
171+
172+
return captchaPromise.finally(() => {
173+
captchaPromise = null;
174+
});
143175
}
144176
145177
function parseErrors(error: any): ErrorMessages {
@@ -329,6 +361,15 @@ onMounted(async () => {
329361
await fetchMessages(true);
330362
}
331363
});
364+
365+
onBeforeUnmount(() => {
366+
const turnstile = (window as unknown as { turnstile?: Turnstile })
367+
.turnstile;
368+
if (turnstile && turnstileWidgetId) {
369+
turnstile.remove(turnstileWidgetId);
370+
turnstileWidgetId = null;
371+
}
372+
});
332373
</script>
333374

334375
<template>

web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"moment": "^2.30.1",
2626
"nuxt": "^4.4.6",
2727
"pinia": "^3.0.4",
28+
"prettier": "^3.8.4",
2829
"pusher-js": "^8.5.0",
2930
"qrcode": "^1.5.4",
3031
"sass": "^1.100.0",

web/pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)