Skip to content

Commit

Permalink
switch to turnstile
Browse files Browse the repository at this point in the history
  • Loading branch information
Teages committed Nov 27, 2023
1 parent b7c49e4 commit 029cf01
Show file tree
Hide file tree
Showing 14 changed files with 341 additions and 290 deletions.
3 changes: 3 additions & 0 deletions assets/css/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ html[lang="ko-KR"] {
body {
@apply bg-black bg-opacity-30 break-words min-w-[380px]
}
html {
@apply overflow-y-scroll
}

/* Scrollbar */

Expand Down
103 changes: 71 additions & 32 deletions components/Captcha.vue
Original file line number Diff line number Diff line change
@@ -1,49 +1,88 @@
<script setup lang="ts">
const { root, execute: _execute, onVerify, onExpired, onError, reset } = useChallengeV2({
options: {
size: 'invisible',
badge: 'bottomleft',
},
})
const token = useState<string>('turnstileToken', () => '')
const error = useState<string>('turnstileError', () => '')
const lock = useState<boolean>('turnstileLock', () => false)
const loaded = useState<boolean>('turnstileLoaded', () => false)
const isMain = ref(false)
const turnstile = ref()
if (process.client && loaded.value === false) {
loaded.value = true
isMain.value = true
}
if (isMain) {
onBeforeUnmount(() => {
isMain.value = false
loaded.value = false
})
watch(token, (value) => {
if (value === '') {
turnstile.value?.reset()
}
})
}
async function execute(): Promise<string> {
await until(lock).toMatch(value => value === false)
const response = await new Promise<string>((resolve, reject) => {
reset()
onVerify((response) => {
resolve(response)
reset()
})
onExpired(() => {
reject(new Error('token expired'))
reset()
lock.value = true
until(token).toMatch(value => value !== '').then(() => {
resolve(token.value)
token.value = ''
lock.value = false
})
onError(() => {
reject(new Error('error'))
reset()
until(error).toMatch(value => value !== '').then(() => {
reject(new Error(error.value === '' ? 'Turnstile timeout' : error.value))
error.value = ''
lock.value = false
})
_execute()
// timeout: 60s
setTimeout(() => {
reject(new Error('timeout'))
reset()
}, 60000)
})
return response
}
onMounted(() => {
useRecaptchaProvider()
})
function onErrorFn(errorStr: string) {
return () => {
error.value = errorStr
}
}
</script>

<template>
<slot :verify="execute" />
<ClientOnly>
<ClientOnly v-if="isMain">
<Teleport to="body">
<div class="google-captcha">
<div ref="root" />
</div>
<dialog
class="modal"
:class="{
'modal-open': lock && token === '',
}"
>
<div class="modal-box w-fit flex flex-col gap-4">
<h3 class="font-bold text-lg">
Turnstile
</h3>
<div class="w-fit">
<NuxtTurnstile
ref="turnstile"
v-model="token"
class="rounded-xl overflow-hidden bg-image-loading"
style="width: 300px; height: 65px;"
data-appearance="interaction-only"
:options="{
'error-callback': onErrorFn('Failed to verify'),
'expired-callback': onErrorFn('Token expired'),
}"
/>
</div>
</div>
<div class="modal-backdrop">
<button @click="onErrorFn('User canceled')()">
Cancel
</button>
</div>
</dialog>
</Teleport>
</ClientOnly>
</template>
</template>
48 changes: 26 additions & 22 deletions components/Comment/Create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,34 @@ const loading = ref(false)
async function sendPost() {
loading.value = true
const res = await useServiceFetch<CommentResponse>(url.value, {
method: 'POST',
body: {
captcha: await props.verify(),
content: post.value,
category: props.category,
key: props.thread,
},
})
if (res.data.value && user.value) {
res.data.value.owner = {
id: user.value.id,
uid: user.value.uid,
name: user.value.name,
avatar: {
small: avatarURL(user.value.id),
original: avatarURL(user.value.id),
medium: avatarURL(user.value.id),
large: avatarURL(user.value.id),
try {
const res = await useServiceFetch<CommentResponse>(url.value, {
method: 'POST',
body: {
captcha: await props.verify(),
content: post.value,
category: props.category,
key: props.thread,
},
})
if (res.data.value && user.value) {
res.data.value.owner = {
id: user.value.id,
uid: user.value.uid,
name: user.value.name,
avatar: {
small: avatarURL(user.value.id),
original: avatarURL(user.value.id),
medium: avatarURL(user.value.id),
large: avatarURL(user.value.id),
},
}
props.afterPost(res.data.value)
post.value = ''
successAlert('Comment Added')
}
props.afterPost(res.data.value)
post.value = ''
successAlert('Comment Added')
} catch (error) {
handleErrorToast(error as Error)
}
loading.value = false
}
Expand Down
2 changes: 1 addition & 1 deletion config/development-local.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"imageURL": "https://images.cytoid.io",
"webURL": "http://localhost:3000",
"cookieDomain": "localhost",
"captchaKey": "6Le6KqsUAAAAANemJwIe18ld-0kKSQn9aqR4-ltM",
"captchaKey": "0x4AAAAAAANth3Rv--EiIENn",
"analyticsCode": "UA-127631599-1"
}
2 changes: 1 addition & 1 deletion config/development.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"imageURL": "https://images.cytoid.io",
"webURL": "http://localhost:3000",
"cookieDomain": "localhost",
"captchaKey": "6Le6KqsUAAAAANemJwIe18ld-0kKSQn9aqR4-ltM",
"captchaKey": "0x4AAAAAAANth3Rv--EiIENn",
"analyticsCode": "UA-127631599-1"
}
2 changes: 1 addition & 1 deletion config/production.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"imageURL": "https://images.cytoid.io",
"webURL": "https://next.cytoid.io",
"cookieDomain": "next.cytoid.io",
"captchaKey": "6Le6KqsUAAAAANemJwIe18ld-0kKSQn9aqR4-ltM",
"captchaKey": "0x4AAAAAAANth3Rv--EiIENn",
"analyticsCode": "UA-127631599-1"
}
9 changes: 5 additions & 4 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default defineNuxtConfig({
'@nuxtjs/tailwindcss',
'nuxt-icon',
'@nuxtjs/google-fonts',
'vue-recaptcha/nuxt',
'@nuxtjs/turnstile',
'@vite-pwa/nuxt',
'@nuxtjs/device',
'nuxt-gtag',
Expand Down Expand Up @@ -51,12 +51,13 @@ export default defineNuxtConfig({
graphqlURLServer: config.get('graphqlURLServer'),
graphqlURLClient: config.get('graphqlURLClient'),
servicesUA: process.env.SERVICES_UA ?? '',
recaptcha: {
v2SiteKey: config.get('captchaKey'),
},
},
},

turnstile: {
siteKey: config.get('captchaKey'),
},

graphqlCodegen: {
config: {
schema: 'gql/schema.graphql',
Expand Down
136 changes: 68 additions & 68 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
{
"name": "cytoid.io",
"type": "module",
"version": "2.0.0",
"private": true,
"description": "Cytoid is a music game where you can create, share and play your own levels! Powered by community, with many dedicated creators, Cytoid provides a huge variety of musical genres to enjoy and a diverse range of gameplay design.",
"scripts": {
"build": "nuxt build",
"start": "node .output/server/index.mjs",
"dev": "nuxt dev",
"dev:local": "cross-env NODE_APP_INSTANCE=local nuxt dev",
"gql": "npx cross-env NODE_ENV=production node ./cli/codegen-update.js",
"gql:local": "npx cross-env NODE_APP_INSTANCE=local node ./cli/codegen-update.js",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
},
"dependencies": {
"graphql": "^16.7.1"
},
"devDependencies": {
"@antfu/eslint-config": "^2.1.0",
"@graphql-codegen/cli": "^5.0.0",
"@graphql-codegen/client-preset": "^4.0.1",
"@nuxt/devtools": "^1.0.3",
"@nuxtjs/device": "^3.1.1",
"@nuxtjs/google-fonts": "^3.0.2",
"@nuxtjs/i18n": "^8.0.0-rc.3",
"@nuxtjs/tailwindcss": "^6.8.0",
"@tailwindcss/typography": "^0.5.9",
"@types/config": "^3.3.0",
"@types/glob": "^8.1.0",
"@types/howler": "^2.2.7",
"@types/lodash": "^4.14.196",
"@types/node": "^20.10.0",
"@types/sanitize-html": "^2.6.2",
"@typescript-eslint/eslint-plugin": "^6.1.0",
"@typescript-eslint/parser": "^6.1.0",
"@urql/core": "^4.1.0",
"@vite-pwa/nuxt": "^0.3.2",
"@vitejs/plugin-legacy": "^5.2.0",
"@vueuse/components": "^10.3.0",
"@vueuse/nuxt": "^10.2.1",
"@wasm-audio-decoders/ogg-vorbis": "^0.1.12",
"apexcharts": "^3.41.0",
"config": "^3.3.9",
"cross-env": "^7.0.3",
"daisyui": "^3.2.1",
"date-fns": "^2.30.0",
"dotenv": "^16.3.1",
"easymde": "^2.18.0",
"eslint": "^8.45.0",
"howler": "^2.2.3",
"marked": "^10.0.0",
"nuxt": "^3.8.0",
"nuxt-gtag": "^1.1.1",
"nuxt-icon": "^0.6.6",
"ogg-opus-decoder": "^1.6.8",
"sanitize-html": "^2.11.0",
"terser": "^5.19.2",
"typescript": "^5.1.6",
"vue-i18n": "9",
"vue-recaptcha": "^3.0.0-alpha.6",
"vue3-apexcharts": "^1.4.4"
}
}
{
"name": "cytoid.io",
"type": "module",
"version": "2.0.0",
"private": true,
"description": "Cytoid is a music game where you can create, share and play your own levels! Powered by community, with many dedicated creators, Cytoid provides a huge variety of musical genres to enjoy and a diverse range of gameplay design.",
"scripts": {
"build": "nuxt build",
"start": "node .output/server/index.mjs",
"dev": "nuxt dev",
"dev:local": "cross-env NODE_APP_INSTANCE=local nuxt dev",
"gql": "npx cross-env NODE_ENV=production node ./cli/codegen-update.js",
"gql:local": "npx cross-env NODE_APP_INSTANCE=local node ./cli/codegen-update.js",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
},
"dependencies": {
"graphql": "^16.7.1"
},
"devDependencies": {
"@antfu/eslint-config": "^2.1.0",
"@graphql-codegen/cli": "^5.0.0",
"@graphql-codegen/client-preset": "^4.0.1",
"@nuxt/devtools": "^1.0.3",
"@nuxtjs/device": "^3.1.1",
"@nuxtjs/google-fonts": "^3.0.2",
"@nuxtjs/i18n": "^8.0.0-rc.3",
"@nuxtjs/tailwindcss": "^6.8.0",
"@nuxtjs/turnstile": "^0.6.3",
"@tailwindcss/typography": "^0.5.9",
"@types/config": "^3.3.0",
"@types/glob": "^8.1.0",
"@types/howler": "^2.2.7",
"@types/lodash": "^4.14.196",
"@types/node": "^20.10.0",
"@types/sanitize-html": "^2.6.2",
"@typescript-eslint/eslint-plugin": "^6.1.0",
"@typescript-eslint/parser": "^6.1.0",
"@urql/core": "^4.1.0",
"@vite-pwa/nuxt": "^0.3.2",
"@vitejs/plugin-legacy": "^5.2.0",
"@vueuse/components": "^10.3.0",
"@vueuse/nuxt": "^10.2.1",
"@wasm-audio-decoders/ogg-vorbis": "^0.1.12",
"apexcharts": "^3.41.0",
"config": "^3.3.9",
"cross-env": "^7.0.3",
"daisyui": "^3.2.1",
"date-fns": "^2.30.0",
"dotenv": "^16.3.1",
"easymde": "^2.18.0",
"eslint": "^8.45.0",
"howler": "^2.2.3",
"marked": "^10.0.0",
"nuxt": "^3.8.0",
"nuxt-gtag": "^1.1.1",
"nuxt-icon": "^0.6.6",
"ogg-opus-decoder": "^1.6.8",
"sanitize-html": "^2.11.0",
"terser": "^5.19.2",
"typescript": "^5.1.6",
"vue-i18n": "9",
"vue3-apexcharts": "^1.4.4"
}
}
2 changes: 1 addition & 1 deletion pages/levels/[id]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ async function downloadLevel(verify: () => Promise<string>) {
}
if (downloadLink.value === '') {
const token = await verify()
try {
const token = await verify()
const { data: res } = await useServiceFetch<levelDownloadResponse>(`/levels/${levelId}/resources`, {
method: 'POST',
body: {
Expand Down
Loading

0 comments on commit 029cf01

Please sign in to comment.