Implement messenger login tokens and bot login endpoint
This commit is contained in:
@@ -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, {
|
||||
|
||||
Reference in New Issue
Block a user