itube-specs 0.0.439 → 0.0.443
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
import type { IPasswordForm } from '../../types';
|
|
41
41
|
import { validateEmail } from '../../runtime';
|
|
42
42
|
import { AuthorizationApiService } from '~/services/api/authorization.service';
|
|
43
|
+
import { useReCaptcha } from 'vue-recaptcha-v3';
|
|
43
44
|
|
|
44
45
|
const {t} = useI18n();
|
|
45
46
|
|
|
@@ -52,8 +53,7 @@ const error = ref({
|
|
|
52
53
|
email: false,
|
|
53
54
|
});
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
const { executeRecaptcha } = useGoogleRecaptcha()
|
|
56
|
+
const { executeRecaptcha, recaptchaLoaded } = useReCaptcha();
|
|
57
57
|
|
|
58
58
|
const emit = defineEmits<{
|
|
59
59
|
(eventName: 'login'): void
|
|
@@ -79,8 +79,8 @@ async function submit() {
|
|
|
79
79
|
|
|
80
80
|
try {
|
|
81
81
|
loading.value = true;
|
|
82
|
-
|
|
83
|
-
form.value.token =
|
|
82
|
+
await recaptchaLoaded();
|
|
83
|
+
form.value.token = await executeRecaptcha('password_reset');
|
|
84
84
|
await useUser(AuthorizationApiService).password(form.value);
|
|
85
85
|
useAuthPopup().closeAuthPopup();
|
|
86
86
|
snackbarTheme.value = 'success';
|
|
@@ -1,83 +1,90 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
2
|
+
<ClientOnly>
|
|
3
|
+
<div
|
|
4
|
+
class="s-auth-register"
|
|
5
|
+
:class="{'_loading': loading}"
|
|
6
|
+
>
|
|
7
|
+
<SIcon
|
|
8
|
+
class="s-auth-register__icon"
|
|
9
|
+
name="user-circle"
|
|
10
|
+
size="40"
|
|
11
|
+
/>
|
|
12
|
+
<p
|
|
13
|
+
v-if="additionalText"
|
|
14
|
+
class="s-auth-register__text"
|
|
15
|
+
>{{ t(additionalText) }}</p>
|
|
16
|
+
<SInput
|
|
17
|
+
v-model="form.username"
|
|
18
|
+
:label="t('auth.username')"
|
|
19
|
+
name="login-name"
|
|
20
|
+
:error="error.username"
|
|
21
|
+
@update:error="(val: boolean) => error.username = val"
|
|
22
|
+
/>
|
|
23
|
+
<SInput
|
|
24
|
+
v-model="form.email"
|
|
25
|
+
:label="t('email')"
|
|
26
|
+
autocomplete="email"
|
|
27
|
+
:error="error.email"
|
|
28
|
+
@update:error="(val: boolean) => error.email = val"
|
|
29
|
+
/>
|
|
30
|
+
<SInput
|
|
31
|
+
v-model="form.password_hash"
|
|
32
|
+
:label="t('auth.password')"
|
|
33
|
+
type="password"
|
|
34
|
+
:error="error.password_hash"
|
|
35
|
+
autocomplete="new-password"
|
|
36
|
+
@update:error="(val: boolean) => error.password_hash = val"
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<div class="s-auth-register__buttons">
|
|
40
|
+
<SButton
|
|
41
|
+
:disabled="loading"
|
|
42
|
+
wide
|
|
43
|
+
size="l"
|
|
44
|
+
@click="submit"
|
|
45
|
+
>{{ t('auth.sign_up') }}
|
|
46
|
+
</SButton>
|
|
47
|
+
<SButton
|
|
48
|
+
wide
|
|
49
|
+
size="l"
|
|
50
|
+
theme="secondary"
|
|
51
|
+
@click="onLoginClick"
|
|
52
|
+
>{{ t('auth.log_in') }}
|
|
53
|
+
</SButton>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<p class="s-auth-register__agreement">{{ t('auth.agree_begin') }}
|
|
57
|
+
<NuxtLink
|
|
58
|
+
class="s-auth-register__agreement-link"
|
|
59
|
+
to="/terms"
|
|
60
|
+
target="_blank"
|
|
61
|
+
>{{ t('auth.agree_terms')}}
|
|
62
|
+
</NuxtLink>{{ t('auth.agree_and')}}
|
|
63
|
+
<NuxtLink
|
|
64
|
+
class="s-auth-register__agreement-link"
|
|
65
|
+
to="/policy"
|
|
66
|
+
target="_blank"
|
|
67
|
+
>{{ t('auth.agree_policy') }}
|
|
68
|
+
</NuxtLink>
|
|
69
|
+
</p>
|
|
53
70
|
</div>
|
|
54
|
-
|
|
55
|
-
<p class="s-auth-register__agreement">{{ t('auth.agree_begin') }}
|
|
56
|
-
<NuxtLink
|
|
57
|
-
class="s-auth-register__agreement-link"
|
|
58
|
-
to="/terms"
|
|
59
|
-
target="_blank"
|
|
60
|
-
>{{ t('auth.agree_terms')}}
|
|
61
|
-
</NuxtLink>{{ t('auth.agree_and')}}<NuxtLink
|
|
62
|
-
class="s-auth-register__agreement-link"
|
|
63
|
-
to="/policy"
|
|
64
|
-
target="_blank"
|
|
65
|
-
>{{ t('auth.agree_policy') }}
|
|
66
|
-
</NuxtLink>
|
|
67
|
-
</p>
|
|
68
|
-
</div>
|
|
71
|
+
</ClientOnly>
|
|
69
72
|
</template>
|
|
70
73
|
|
|
71
74
|
<script setup lang="ts">
|
|
72
75
|
import type { IRegistrateForm } from '../../types';
|
|
73
76
|
import { validateEmail, validatePassword, validateUsername } from '../../runtime';
|
|
74
77
|
import { AuthorizationApiService } from '~/services/api/authorization.service';
|
|
78
|
+
import { useReCaptcha } from 'vue-recaptcha-v3';
|
|
75
79
|
|
|
76
80
|
defineProps<{
|
|
77
81
|
additionalText?: string;
|
|
78
82
|
}>()
|
|
79
83
|
|
|
80
|
-
const {t} = useI18n();
|
|
84
|
+
const { t } = useI18n();
|
|
85
|
+
|
|
86
|
+
// Правильное использование composable для Vue 3
|
|
87
|
+
const { executeRecaptcha, recaptchaLoaded } = useReCaptcha();
|
|
81
88
|
|
|
82
89
|
const form = ref({
|
|
83
90
|
username: '',
|
|
@@ -104,8 +111,6 @@ const loading = ref(false);
|
|
|
104
111
|
|
|
105
112
|
const { setErrorState, snackbarText, snackbarTheme, showErrorSnack, resetSnackbar } = useSnackbar();
|
|
106
113
|
|
|
107
|
-
const { executeRecaptcha } = useGoogleRecaptcha();
|
|
108
|
-
|
|
109
114
|
function validateForm(): boolean {
|
|
110
115
|
const { username, email, password_hash } = form.value;
|
|
111
116
|
|
|
@@ -115,19 +120,12 @@ function validateForm(): boolean {
|
|
|
115
120
|
password_hash: !validatePassword(password_hash),
|
|
116
121
|
};
|
|
117
122
|
|
|
118
|
-
if (!validateEmail(email))
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (!validatePassword(password_hash)) {
|
|
122
|
-
showErrorSnack('error_password');
|
|
123
|
-
}
|
|
124
|
-
if (!validateUsername(username)) {
|
|
125
|
-
showErrorSnack('error_username');
|
|
126
|
-
}
|
|
123
|
+
if (!validateEmail(email)) showErrorSnack('error_email');
|
|
124
|
+
if (!validatePassword(password_hash)) showErrorSnack('error_password');
|
|
125
|
+
if (!validateUsername(username)) showErrorSnack('error_username');
|
|
127
126
|
|
|
128
127
|
error.value = errors;
|
|
129
128
|
|
|
130
|
-
|
|
131
129
|
return !Object.values(errors).some(Boolean);
|
|
132
130
|
}
|
|
133
131
|
|
|
@@ -140,14 +138,19 @@ async function submit() {
|
|
|
140
138
|
|
|
141
139
|
try {
|
|
142
140
|
loading.value = true;
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
|
|
142
|
+
await recaptchaLoaded();
|
|
143
|
+
form.value.token = await executeRecaptcha('register');
|
|
144
|
+
|
|
145
145
|
await useUser(AuthorizationApiService).register(form.value);
|
|
146
|
+
|
|
146
147
|
useAuthPopup().closeAuthPopup();
|
|
147
148
|
snackbarTheme.value = 'success';
|
|
148
149
|
snackbarText.value = 'Registration success';
|
|
149
150
|
} catch (err) {
|
|
150
151
|
setErrorState(err);
|
|
152
|
+
// Опционально: обработка ошибки reCAPTCHA (например, если загрузка не удалась)
|
|
153
|
+
console.error('reCAPTCHA error:', err);
|
|
151
154
|
} finally {
|
|
152
155
|
loading.value = false;
|
|
153
156
|
}
|
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
import { reportFormsScheme } from '../../lib/report-forms-scheme';
|
|
115
115
|
import { EReportFormsSubjects, validateEmail, validatePhone } from '../../runtime';
|
|
116
116
|
import type { InputTypes, IReportForm, IReportRequest } from '../../types';
|
|
117
|
+
import { useReCaptcha } from 'vue-recaptcha-v3';
|
|
117
118
|
|
|
118
119
|
const reasonValue = ref('');
|
|
119
120
|
const errorRadio = ref(false);
|
|
@@ -138,7 +139,7 @@ const loading = ref(false);
|
|
|
138
139
|
const activeCategory = computed(() => reportFormsScheme.find((subItem) => subItem.subject === form.value.categoryName))
|
|
139
140
|
const requiredFields = computed(() => activeCategory.value?.items?.filter(item => item.required).map(item => item.value));
|
|
140
141
|
|
|
141
|
-
const { executeRecaptcha } =
|
|
142
|
+
const { executeRecaptcha, recaptchaLoaded } = useReCaptcha();
|
|
142
143
|
|
|
143
144
|
const { snackbarText, snackbarTheme, showErrorSnack, resetSnackbar } = useSnackbar();
|
|
144
145
|
|
|
@@ -195,8 +196,8 @@ async function submit() {
|
|
|
195
196
|
try {
|
|
196
197
|
const baseURL = window.location.origin;
|
|
197
198
|
loading.value = true;
|
|
198
|
-
|
|
199
|
-
form.value.token =
|
|
199
|
+
await recaptchaLoaded();
|
|
200
|
+
form.value.token = await executeRecaptcha('contact_form');
|
|
200
201
|
form.value.url = `${baseURL}/videos/${reportedVideoCard.value.id}`;
|
|
201
202
|
|
|
202
203
|
if (reasonValue.value) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "itube-specs",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.443",
|
|
5
5
|
"main": "./nuxt.config.ts",
|
|
6
6
|
"types": "./types/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@vueform/slider": "2.1.10",
|
|
52
|
-
"@vueuse/core": "12.8.2"
|
|
52
|
+
"@vueuse/core": "12.8.2",
|
|
53
|
+
"vue-recaptcha-v3": "^2.0.1"
|
|
53
54
|
}
|
|
54
55
|
}
|