Add Telegram Mini App auth flow
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
isManagerRole,
|
||||
} from './access.js';
|
||||
import { sendLoginCodeEmail } from './mailer.js';
|
||||
import { upsertActiveMessengerConnection } from './messenger-connections.js';
|
||||
import { dispatchToUserConnections, sendMessengerMessage } from './messenger.js';
|
||||
import { dateTimeScalar, jsonScalar } from './scalars.js';
|
||||
import { fetchTelegramConnectionProfile } from './telegram.js';
|
||||
@@ -281,6 +282,33 @@ function formatOrderStatusMessage(order, status, note) {
|
||||
return `Заказ ${order.code} изменил статус: ${status}.${suffix}`;
|
||||
}
|
||||
|
||||
function buildFrontendAppUrl(path) {
|
||||
const baseUrl = String(
|
||||
process.env.TELEGRAM_MINI_APP_URL ||
|
||||
process.env.WEB_FRONTEND_URL ||
|
||||
process.env.NUXT_PUBLIC_SITE_URL ||
|
||||
'',
|
||||
).trim().replace(/\/$/, '');
|
||||
|
||||
const normalizedPath = String(path || '').trim();
|
||||
if (!baseUrl || !normalizedPath.startsWith('/')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return `${baseUrl}${normalizedPath}`;
|
||||
}
|
||||
|
||||
function buildUserOrderPath(orderId, role) {
|
||||
const normalizedOrderId = String(orderId || '').trim();
|
||||
if (!normalizedOrderId) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return isManagerRole(role)
|
||||
? `/client-orders/${normalizedOrderId}`
|
||||
: `/orders/${normalizedOrderId}`;
|
||||
}
|
||||
|
||||
async function notifyOrderStakeholders(context, order, status, note) {
|
||||
const recipients = [order.customerId, order.managerId].filter(Boolean);
|
||||
if (!recipients.length) {
|
||||
@@ -289,8 +317,22 @@ async function notifyOrderStakeholders(context, order, status, note) {
|
||||
|
||||
const message = formatOrderStatusMessage(order, status, note);
|
||||
const uniqueRecipients = [...new Set(recipients)];
|
||||
const users = await context.prisma.user.findMany({
|
||||
where: {
|
||||
id: { in: uniqueRecipients },
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
role: true,
|
||||
},
|
||||
});
|
||||
const userRoleMap = new Map(users.map((user) => [user.id, user.role]));
|
||||
|
||||
await Promise.allSettled(
|
||||
uniqueRecipients.map((userId) => dispatchToUserConnections(context.prisma, userId, message)),
|
||||
uniqueRecipients.map((userId) => dispatchToUserConnections(context.prisma, userId, message, {
|
||||
buttonUrl: buildFrontendAppUrl(buildUserOrderPath(order.id, userRoleMap.get(userId))),
|
||||
buttonText: 'Открыть заказ',
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -820,41 +862,11 @@ export const resolvers = {
|
||||
}
|
||||
|
||||
if (login.messengerConnection) {
|
||||
await context.prisma.messengerConnection.updateMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
type: login.messengerConnection.type,
|
||||
isActive: true,
|
||||
NOT: { channelId: login.messengerConnection.channelId },
|
||||
},
|
||||
data: { isActive: false },
|
||||
});
|
||||
|
||||
await context.prisma.messengerConnection.upsert({
|
||||
where: {
|
||||
userId_type_channelId: {
|
||||
userId: user.id,
|
||||
type: login.messengerConnection.type,
|
||||
channelId: login.messengerConnection.channelId,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
isActive: true,
|
||||
displayName: login.messengerConnection.displayName ?? null,
|
||||
username: login.messengerConnection.username ?? null,
|
||||
avatarFileId: login.messengerConnection.avatarFileId ?? null,
|
||||
avatarFileUniqueId: login.messengerConnection.avatarFileUniqueId ?? null,
|
||||
},
|
||||
create: {
|
||||
userId: user.id,
|
||||
type: login.messengerConnection.type,
|
||||
channelId: login.messengerConnection.channelId,
|
||||
isActive: true,
|
||||
displayName: login.messengerConnection.displayName ?? null,
|
||||
username: login.messengerConnection.username ?? null,
|
||||
avatarFileId: login.messengerConnection.avatarFileId ?? null,
|
||||
avatarFileUniqueId: login.messengerConnection.avatarFileUniqueId ?? null,
|
||||
},
|
||||
await upsertActiveMessengerConnection(context.prisma, {
|
||||
userId: user.id,
|
||||
type: login.messengerConnection.type,
|
||||
channelId: login.messengerConnection.channelId,
|
||||
profile: login.messengerConnection,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user