67 lines
2.2 KiB
JavaScript
67 lines
2.2 KiB
JavaScript
import { pool } from "../db.js";
|
|
|
|
const TOKEN_TTL_SEC = 600; // 10 минут
|
|
|
|
export async function createTgLoginToken({ token, intent, userId, ipAddress, userAgent }) {
|
|
const expires = new Date(Date.now() + TOKEN_TTL_SEC * 1000);
|
|
await pool.query(
|
|
`INSERT INTO uno_bff.tg_login_tokens
|
|
(token, intent, status, user_id, ip_address, user_agent, expires_at)
|
|
VALUES ($1, $2, 'pending', $3, $4, $5, $6)`,
|
|
[token, intent, userId || null, ipAddress, userAgent, expires]
|
|
);
|
|
return { token, expiresAt: expires, ttlSec: TOKEN_TTL_SEC };
|
|
}
|
|
|
|
export async function findTgLoginToken(token) {
|
|
const r = await pool.query(
|
|
`SELECT * FROM uno_bff.tg_login_tokens WHERE token = $1`, [token]
|
|
);
|
|
return r.rows[0] || null;
|
|
}
|
|
|
|
export async function markTgTokenConfirmed(token, { telegramId, telegramUsername, telegramFirstName, telegramLastName, userId }) {
|
|
await pool.query(
|
|
`UPDATE uno_bff.tg_login_tokens
|
|
SET status = 'confirmed',
|
|
telegram_id = $2,
|
|
telegram_username = $3,
|
|
telegram_first_name = $4,
|
|
telegram_last_name = $5,
|
|
user_id = COALESCE($6, user_id),
|
|
confirmed_at = now()
|
|
WHERE token = $1 AND status = 'pending' AND expires_at > now()`,
|
|
[token, telegramId, telegramUsername, telegramFirstName, telegramLastName, userId || null]
|
|
);
|
|
}
|
|
|
|
export async function markTgTokenError(token, errorCode) {
|
|
await pool.query(
|
|
`UPDATE uno_bff.tg_login_tokens
|
|
SET status = 'error', error_code = $2
|
|
WHERE token = $1 AND status = 'pending'`,
|
|
[token, errorCode]
|
|
);
|
|
}
|
|
|
|
export async function consumeTgToken(token) {
|
|
const r = await pool.query(
|
|
`UPDATE uno_bff.tg_login_tokens
|
|
SET status = 'consumed', consumed_at = now()
|
|
WHERE token = $1 AND status = 'confirmed'
|
|
RETURNING *`,
|
|
[token]
|
|
);
|
|
return r.rows[0] || null;
|
|
}
|
|
|
|
export async function countTgStartsByIpLastMinutes(ipAddress, minutes = 10) {
|
|
if (!ipAddress) return 0;
|
|
const r = await pool.query(
|
|
`SELECT count(*)::int AS c FROM uno_bff.tg_login_tokens
|
|
WHERE ip_address = $1 AND created_at > now() - ($2 || ' minutes')::interval`,
|
|
[ipAddress, String(minutes)]
|
|
);
|
|
return r.rows[0]?.c || 0;
|
|
}
|