feat(auth): request secure messenger start sessions

This commit is contained in:
Ruslan Bakiev
2026-04-03 18:12:17 +07:00
parent 93b6c51625
commit 6cadd5160c
6 changed files with 190 additions and 65 deletions

View File

@@ -5,7 +5,7 @@ import {
RequestLoginCodeDocument,
VerifyLoginCodeDocument,
} from '~/composables/graphql/generated';
import { buildMessengerBotStartUrl } from '~/composables/useMessengerBotLink';
import { useMessengerStart } from '~/composables/useMessengerStart';
const config = useRuntimeConfig();
const route = useRoute();
@@ -29,6 +29,7 @@ const lastRequestedEmail = ref('');
const requestCodeMutation = useMutation(RequestLoginCodeDocument, { throws: 'never' });
const verifyCodeMutation = useMutation(VerifyLoginCodeDocument, { throws: 'never' });
const consumeLoginTokenMutation = useMutation(ConsumeLoginTokenDocument, { throws: 'never' });
const { openMessengerBot, pendingChannel } = useMessengerStart();
const telegramBotUrl = computed(() => config.public.telegramBotUrl || '');
const maxBotUrl = computed(() => config.public.maxBotUrl || '');
@@ -36,13 +37,6 @@ const maxBotUrl = computed(() => config.public.maxBotUrl || '');
const normalizedEmail = computed(() => email.value.trim().toLowerCase());
const isEmailReady = computed(() => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(normalizedEmail.value));
const telegramLoginUrl = computed(() =>
isEmailReady.value ? buildMessengerBotStartUrl(telegramBotUrl.value, normalizedEmail.value) : '',
);
const maxLoginUrl = computed(() =>
isEmailReady.value ? buildMessengerBotStartUrl(maxBotUrl.value, normalizedEmail.value) : '',
);
async function finalizeSession(accessToken: string) {
authCookie.value = accessToken;
}
@@ -167,6 +161,28 @@ async function consumeLoginToken(loginToken: string) {
await navigateAfterLogin(payload.user);
}
async function startMessengerLogin(channel: 'TELEGRAM' | 'MAX') {
if (!isEmailReady.value) {
feedback.value = 'Введите корректный email.';
feedbackTone.value = 'error';
return;
}
const baseUrl = channel === 'TELEGRAM' ? telegramBotUrl.value : maxBotUrl.value;
if (!baseUrl) {
feedback.value = 'Ссылка на бота пока не настроена.';
feedbackTone.value = 'error';
return;
}
feedback.value = '';
await openMessengerBot({
channel,
baseUrl,
email: normalizedEmail.value,
});
}
function scheduleAutoRequest() {
clearAutoRequestTimer();
@@ -242,24 +258,22 @@ onBeforeUnmount(() => {
</fieldset>
<div class="grid gap-2 sm:grid-cols-2">
<a
:href="telegramLoginUrl || undefined"
target="_blank"
rel="noopener noreferrer"
<button
class="btn btn-secondary"
:class="{ 'btn-disabled pointer-events-none': !telegramLoginUrl }"
:class="{ 'btn-disabled pointer-events-none': !telegramBotUrl || !isEmailReady }"
:disabled="pendingChannel === 'TELEGRAM' || !telegramBotUrl || !isEmailReady"
@click="startMessengerLogin('TELEGRAM')"
>
Войти через Telegram
</a>
<a
:href="maxLoginUrl || undefined"
target="_blank"
rel="noopener noreferrer"
{{ pendingChannel === 'TELEGRAM' ? 'Открываем Telegram…' : 'Войти через Telegram' }}
</button>
<button
class="btn btn-accent"
:class="{ 'btn-disabled pointer-events-none': !maxLoginUrl }"
:class="{ 'btn-disabled pointer-events-none': !maxBotUrl || !isEmailReady }"
:disabled="pendingChannel === 'MAX' || !maxBotUrl || !isEmailReady"
@click="startMessengerLogin('MAX')"
>
Войти через Max
</a>
{{ pendingChannel === 'MAX' ? 'Открываем Max…' : 'Войти через Max' }}
</button>
</div>
<p v-if="requestCodeMutation.loading.value" class="text-sm text-base-content/70">