Skip to content

Commit a5e78b4

Browse files
committed
feat: add recaptcha
1 parent 5b5dfd8 commit a5e78b4

File tree

9 files changed

+75
-15
lines changed

9 files changed

+75
-15
lines changed

.env-example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
VITE_reCAPTCHA_SITE_KEY = "GOOGLE_SITEKEY"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ node_modules
1111
dist
1212
dist-ssr
1313
*.local
14+
.env
1415

1516
# Editor directories and files
1617
.vscode/*

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
<body>
1010
<div id="app"></div>
1111
<script type="module" src="/src/main.ts"></script>
12+
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
1213
</body>
1314
</html>

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"pinia": "^2.1.7",
1515
"vue": "^3.4.15",
1616
"vue-router": "^4.2.5",
17+
"vue-recaptcha": "2.0.3",
1718
"vue3-lottie": "^3.2.0"
1819
},
1920
"devDependencies": {

pnpm-lock.yaml

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

src/components/faucet/FaucetDetail.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const gnoRequestLogo = ref<HTMLElement | null>(null)
4545
const popupHeight = reactive({ from: 0, to: 0 })
4646
const error = ref<Status | null>(null)
4747
48-
const requestFaucet = async (address: string, amount: number) => {
48+
const requestFaucet = async (address: string, amount: number, secret: string) => {
4949
popupHeight.from = DOMpopup.value?.getBoundingClientRect().height ?? 0
5050
gsap.set(DOMpopup.value, { height: popupHeight.from + 'px' })
5151
@@ -62,6 +62,7 @@ const requestFaucet = async (address: string, amount: number) => {
6262
//TODO: Request - replace fake request
6363
console.log(address)
6464
console.log(amount)
65+
console.log(secret)
6566
6667
const res = await req('success')
6768
store.status = res.code

src/components/faucet/content/FaucetContentForm.vue

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
11
<template>
22
<div>
33
<h2 class="text-600 mb-12">{{ name }}</h2>
4-
<form class="w-full space-y-12">
5-
<Input
6-
:label="'Enter your wallet address'"
7-
:placeholder="'e.g. g1juwee0ynsdvaukvxk3j5s4cl6nn24uxwlydxrl'"
8-
v-model="bindAddress"
9-
/>
10-
<Select
11-
v-if="store.selectedFaucet.amounts"
12-
:label="'Select faucet amount'"
13-
:options="options"
14-
@update="(option) => SelectAmount(option)"
15-
/>
4+
<form class="w-full space-y-12" @submit.prevent="requestFaucet">
5+
<Input :label="'Enter your wallet address'" :placeholder="'e.g. g1juwee0ynsdvaukvxk3j5s4cl6nn24uxwlydxrl'" v-model="bindAddress" />
6+
<Select v-if="store.selectedFaucet.amounts" :label="'Select faucet amount'" :options="options" @update="(option) => SelectAmount(option)" />
7+
<Recaptcha @validation="captchaValidation" />
168
<div>
179
<div class="flex gap-4">
1810
<Button text="Cancel" variant="outline" @click.prevent="() => closePopup()" class="w-full" />
19-
<Button text="Request Faucet" class="w-full" @click.prevent="() => requestFaucet()" />
11+
<Button text="Request Faucet" class="w-full" type="submit" />
2012
</div>
2113
<div v-if="error" class="text-center text-red-200 mt-6">{{ errorDetail[error] }}</div>
2214
</div>
@@ -27,9 +19,12 @@
2719
<script setup lang="ts">
2820
import { ref } from 'vue'
2921
22+
import VueRecaptcha from 'vue-recaptcha'
23+
3024
import Input from '@/components/ui/Input.vue'
3125
import Select from '@/components/ui/Select.vue'
3226
import Button from '@/components/ui/Button.vue'
27+
import Recaptcha from '@/components/ui/Recaptcha.vue'
3328
3429
import { useFaucetDetail } from '@/stores/faucetDetail'
3530
@@ -46,6 +41,13 @@ const store = useFaucetDetail()
4641
4742
const bindAddress = ref('')
4843
const amount = ref<SelectOption | null>(null)
44+
const captchaValid = ref(false)
45+
const captchaSecret = ref('')
46+
47+
const captchaValidation = ({ code = 'error', secret = '' }) => {
48+
captchaValid.value = code === 'success'
49+
captchaSecret.value = secret
50+
}
4951
5052
const SelectAmount = (option: SelectOption) => {
5153
amount.value = option
@@ -62,6 +64,7 @@ const errorDetail = {
6264
}
6365
6466
const requestFaucet = () => {
65-
emit('requestFaucet', bindAddress.value, store.selectedFaucet.amounts && amount.value?.value)
67+
if (captchaValid.value === false) return
68+
emit('requestFaucet', bindAddress.value, store.selectedFaucet.amounts && amount.value?.value, captchaSecret.value)
6669
}
6770
</script>

src/components/ui/Recaptcha.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<template>
2+
<vue-recaptcha :sitekey="siteKey" @verify="handleSuccess" @error="handleError"></vue-recaptcha>
3+
</template>
4+
5+
<script setup lang="ts">
6+
import { ref } from 'vue'
7+
8+
const siteKey = ref(import.meta.env.VITE_reCAPTCHA_SITE_KEY ?? '')
9+
10+
const emit = defineEmits(['validation'])
11+
12+
const handleError = (res: string) => {
13+
emit('validation', { code: 'error', secret: res })
14+
}
15+
16+
const handleSuccess = (res: string) => {
17+
emit('validation', { code: 'success', secret: res })
18+
}
19+
</script>

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { createApp } from 'vue'
22
import { createPinia } from 'pinia'
3+
import { VueRecaptcha } from 'vue-recaptcha'
34
import './style.css'
45
import App from './App.vue'
56

67
const pinia = createPinia()
78
const app = createApp(App)
89

910
app.use(pinia)
11+
app.component('vue-recaptcha', VueRecaptcha)
1012
app.mount('#app')

0 commit comments

Comments
 (0)