diff --git a/app/pages/login.vue b/app/pages/login.vue index 33548a4..5c3c594 100644 --- a/app/pages/login.vue +++ b/app/pages/login.vue @@ -6,8 +6,6 @@ import { VerifyLoginCodeDocument, } from '~/composables/graphql/generated'; -type LoginChannel = 'EMAIL' | 'TELEGRAM' | 'MAX'; - const config = useRuntimeConfig(); const route = useRoute(); const authCookieName = config.public.authCookieName || 'fregat_auth_token'; @@ -17,15 +15,13 @@ const authCookie = useCookie(authCookieName, { }); const step = ref<'request' | 'verify'>('request'); -const channel = ref('EMAIL'); -const destination = ref(''); +const email = ref(''); const challengeToken = ref(''); -const maskedDestination = ref(''); +const maskedEmail = ref(''); const expiresAt = ref(''); const code = ref(''); const feedback = ref(''); const feedbackTone = ref<'success' | 'error'>('success'); -const userIdForBot = ref(''); const requestCodeMutation = useMutation(RequestLoginCodeDocument); const verifyCodeMutation = useMutation(VerifyLoginCodeDocument); @@ -33,14 +29,22 @@ const consumeLoginTokenMutation = useMutation(ConsumeLoginTokenDocument); const telegramBotUrl = computed(() => config.public.telegramBotUrl || ''); const maxBotUrl = computed(() => config.public.maxBotUrl || ''); -const selectedBotUrl = computed(() => - channel.value === 'TELEGRAM' - ? telegramBotUrl.value - : maxBotUrl.value, -); -const startCommand = computed(() => - userIdForBot.value.trim() ? `/start ${userIdForBot.value.trim()}` : '/start <ваш_user_id>', -); + +const normalizedEmail = computed(() => email.value.trim().toLowerCase()); +const isEmailReady = computed(() => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(normalizedEmail.value)); + +function buildBotLoginUrl(baseUrl: string) { + if (!isEmailReady.value || !baseUrl) { + return ''; + } + + const payload = encodeURIComponent(`login:${normalizedEmail.value}`); + const separator = baseUrl.includes('?') ? '&' : '?'; + return `${baseUrl}${separator}start=${payload}`; +} + +const telegramLoginUrl = computed(() => buildBotLoginUrl(telegramBotUrl.value)); +const maxLoginUrl = computed(() => buildBotLoginUrl(maxBotUrl.value)); async function finalizeSession(accessToken: string) { authCookie.value = accessToken; @@ -48,8 +52,8 @@ async function finalizeSession(accessToken: string) { } async function requestCode() { - if (channel.value !== 'EMAIL') { - feedback.value = 'Кодовый вход доступен только для Email.'; + if (!isEmailReady.value) { + feedback.value = 'Введите корректный email.'; feedbackTone.value = 'error'; return; } @@ -57,8 +61,8 @@ async function requestCode() { feedback.value = ''; const result = await requestCodeMutation.mutate({ input: { - channel: channel.value, - destination: destination.value.trim(), + channel: 'EMAIL', + destination: normalizedEmail.value, }, }); @@ -70,9 +74,9 @@ async function requestCode() { } challengeToken.value = payload.challengeToken; - maskedDestination.value = payload.destination; + maskedEmail.value = payload.destination; expiresAt.value = new Date(payload.expiresAt).toLocaleString(); - feedback.value = `Код отправлен на ${payload.destination}. Тестовый код сейчас: 123456`; + feedback.value = `Код отправлен на ${payload.destination}.`; feedbackTone.value = 'success'; step.value = 'verify'; } @@ -110,19 +114,6 @@ async function consumeLoginToken(loginToken: string) { await finalizeSession(payload.accessToken); } -function copyStartCommand() { - navigator.clipboard.writeText(startCommand.value); - feedback.value = `Команда скопирована: ${startCommand.value}`; - feedbackTone.value = 'success'; -} - -watch(channel, () => { - feedback.value = ''; - if (channel.value !== 'EMAIL') { - step.value = 'request'; - } -}); - onMounted(async () => { const loginToken = typeof route.query.login_token === 'string' ? route.query.login_token : ''; if (loginToken) { @@ -138,48 +129,60 @@ onMounted(async () => {

Вход в личный кабинет

- Email вход по коду. Telegram/Max вход через бота и временный токен. + Введите email и выберите способ входа.

-
-
- - - -
-
- -
+
Email адрес - +
+ + + +

+ Для кнопок бота нужно задать `NUXT_PUBLIC_TELEGRAM_BOT_URL` и `NUXT_PUBLIC_MAX_BOT_URL`. +

-
+
- Код отправлен на {{ maskedDestination }}. + Код отправлен на {{ maskedEmail }}. Действителен до: {{ expiresAt }}.
@@ -204,48 +207,10 @@ onMounted(async () => {
-
-
- Откройте {{ channel === 'TELEGRAM' ? 'Telegram' : 'Max' }}-бота, отправьте команду - {{ startCommand }}, затем передайте боту свой user_id. - Бот пришлёт кнопку входа в кабинет с временным токеном. -
- -
- Ваш user_id - - -
- -
- - - Открыть бота - -
- -

- Ссылка на {{ channel === 'TELEGRAM' ? 'Telegram' : 'Max' }}-бота не настроена в env. -

-
-