Implement messenger login tokens and bot login endpoint

This commit is contained in:
Ruslan Bakiev
2026-04-01 19:20:42 +07:00
parent 8c8689a877
commit 23edfbe7ff
5 changed files with 172 additions and 41 deletions

View File

@@ -8,7 +8,9 @@ import express from 'express';
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@as-integrations/express5';
import { issueTemporaryLoginToken } from './auth.js';
import { buildContext } from './context.js';
import { sendMessengerMessage } from './messenger.js';
import { prisma } from './prisma-client.js';
import { resolvers } from './resolvers.js';
@@ -29,6 +31,78 @@ app.get('/healthz', (_, res) => {
res.json({ status: 'ok' });
});
app.post('/bot/messenger-login', async (req, res) => {
const webhookToken = process.env.BOT_LOGIN_WEBHOOK_TOKEN;
const providedToken = req.body?.token;
if (!webhookToken || providedToken !== webhookToken) {
res.status(401).json({ error: 'Unauthorized bot request.' });
return;
}
const channel = String(req.body?.channel || '').toUpperCase();
if (channel !== 'TELEGRAM' && channel !== 'MAX') {
res.status(400).json({ error: 'Unsupported channel.' });
return;
}
const userId = String(req.body?.userId || '').trim();
const channelId = String(req.body?.channelId || '').trim();
if (!userId || !channelId) {
res.status(400).json({ error: 'userId and channelId are required.' });
return;
}
const user = await prisma.user.findUnique({ where: { id: userId } });
if (!user) {
res.status(404).json({ error: 'User not found.' });
return;
}
await prisma.messengerConnection.upsert({
where: {
userId_type_channelId: {
userId: user.id,
type: channel,
channelId,
},
},
update: { isActive: true },
create: {
userId: user.id,
type: channel,
channelId,
isActive: true,
},
});
const login = issueTemporaryLoginToken(user.id);
const frontendUrl = (
process.env.WEB_FRONTEND_URL ||
process.env.NUXT_PUBLIC_SITE_URL ||
'http://localhost:3000'
).replace(/\/$/, '');
const loginUrl = `${frontendUrl}/login?login_token=${encodeURIComponent(login.loginToken)}`;
const dispatch = await sendMessengerMessage({
type: channel,
channelId,
message: 'Вход подтвержден. Нажмите кнопку, чтобы открыть личный кабинет.',
buttonUrl: loginUrl,
buttonText: 'Открыть кабинет',
});
if (!dispatch.success) {
res.status(502).json({ error: dispatch.detail });
return;
}
res.json({
ok: true,
loginUrl,
expiresAt: login.expiresAt.toISOString(),
});
});
app.use(
'/graphql',
expressMiddleware(server, {