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

@@ -1,21 +1,10 @@
function toBase64Url(value: string) {
if (typeof Buffer !== 'undefined') {
return Buffer.from(value, 'utf8').toString('base64url');
}
return btoa(value)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/g, '');
}
export function buildMessengerBotStartUrl(baseUrl: string, email: string) {
const normalizedEmail = email.trim().toLowerCase();
if (!baseUrl || !normalizedEmail) {
export function buildMessengerBotStartUrl(baseUrl: string, startToken: string) {
const normalizedToken = startToken.trim();
if (!baseUrl || !normalizedToken) {
return '';
}
const payload = encodeURIComponent(toBase64Url(`login:${normalizedEmail}`));
const payload = encodeURIComponent(normalizedToken);
const separator = baseUrl.includes('?') ? '&' : '?';
return `${baseUrl}${separator}start=${payload}`;
}

View File

@@ -0,0 +1,49 @@
import { buildMessengerBotStartUrl } from '~/composables/useMessengerBotLink';
type MessengerChannel = 'TELEGRAM' | 'MAX';
type MessengerStartResponse = {
ok: true;
startToken: string;
expiresAt: string;
mode: 'login' | 'connect';
};
type MessengerStartInput = {
channel: MessengerChannel;
baseUrl: string;
email?: string;
};
export function useMessengerStart() {
const pendingChannel = ref<MessengerChannel | null>(null);
async function openMessengerBot({ channel, baseUrl, email }: MessengerStartInput) {
pendingChannel.value = channel;
const payloadPromise = $fetch<MessengerStartResponse>('/api/auth/messenger-start', {
method: 'POST',
body: {
channel,
email,
},
});
payloadPromise.finally(() => {
pendingChannel.value = null;
});
const payload = await payloadPromise;
const startUrl = buildMessengerBotStartUrl(baseUrl, payload.startToken);
if (import.meta.client) {
window.open(startUrl, '_blank', 'noopener,noreferrer');
}
return payload;
}
return {
pendingChannel,
openMessengerBot,
};
}