diff --git a/src/db/models/Contact.helper.ts b/src/db/models/Contact.helper.ts index e69de29..857aef5 100644 --- a/src/db/models/Contact.helper.ts +++ b/src/db/models/Contact.helper.ts @@ -0,0 +1,47 @@ +import { Op } from "sequelize"; +import { strings_en } from "../../strings"; +import { sendTelegramMessage } from "../../telegram"; +import { TelegramID } from "../../types"; +import { Contact, ContactInterface } from "./Contact"; +import { getUserByTelegramID } from "./User.helper"; + +export async function purgeOldContacts(telegramID: TelegramID): Promise { + const user = await getUserByTelegramID(telegramID); + if (!user) throw new Error("User could not be found"); + const contacts = await Contact.findAll({ + where: { + [Op.or]: [{ user: user.id }, { with: user.id }], + }, + }); + let oldContacts: ContactInterface[] = []; + const currentTime = new Date().getTime(); + contacts.forEach((contact) => { + if (!contact.createdAt) + throw new Error("Creation time not set for contact."); + const contactAge = currentTime - contact.createdAt.getTime(); + if (contactAge > 60 * 60 * 24 * 14 * 1000) { + oldContacts.push(contact); + } + }); + oldContacts.forEach(async (contact) => { + await contact.destroy(); + }); +} + +export async function addContact( + userATelegram: TelegramID, + userBTelegram: TelegramID +): Promise { + const userA = await getUserByTelegramID(userATelegram); + const userB = await getUserByTelegramID(userBTelegram); + + if (!userA || !userB) { + throw new Error("Could not found users"); + } + + await purgeOldContacts(userATelegram); + await purgeOldContacts(userBTelegram); + + await Contact.create({ user: userA.id, with: userB.id }); + await sendTelegramMessage(userB.telegram, strings_en.telegram_qr_scanned); +} diff --git a/src/db/models/Contact.ts b/src/db/models/Contact.ts index c009cca..ad2416b 100644 --- a/src/db/models/Contact.ts +++ b/src/db/models/Contact.ts @@ -5,6 +5,8 @@ import { sequelize } from "../db"; interface ContactAttributes { user: UserRowID; with: UserRowID; + createdAt?: Date; + id?: Number; } export interface ContactInterface extends Model, diff --git a/src/db/models/User.helper.ts b/src/db/models/User.helper.ts index 9a1df10..a88d158 100644 --- a/src/db/models/User.helper.ts +++ b/src/db/models/User.helper.ts @@ -1,6 +1,15 @@ import { TelegramID, UserRowID, VerificationString } from "../../types"; import { User, UserInstance } from "./User"; +export async function createUser( + telegram: TelegramID +): Promise { + const user = await User.create({ + telegram: telegram, + }); + return user; +} + export async function getUserByTelegramID( telegramID: TelegramID ): Promise { diff --git a/src/db/utils.ts b/src/db/utils.ts deleted file mode 100644 index 3379e82..0000000 --- a/src/db/utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { strings_en } from "../strings"; -import { sendTelegramMessage } from "../telegram"; -import { TelegramID } from "../types"; -import { Contact } from "./models/Contact"; -import { User, UserInstance } from "./models/User"; -import { getUserByTelegramID } from "./models/User.helper"; - -export async function addContact( - userATelegram: TelegramID, - userBTelegram: TelegramID -): Promise { - const userA = await getUserByTelegramID(userATelegram); - const userB = await getUserByTelegramID(userBTelegram); - - if (!userA || !userB) { - throw new Error("Could not found users"); - } - - await Contact.create({ user: userA.id, with: userB.id }); - await sendTelegramMessage(userB.telegram, strings_en.telegram_qr_scanned); -} - -export async function createUser( - telegram: TelegramID -): Promise { - const user = await User.create({ - telegram: telegram, - }); - return user; -} diff --git a/src/routes/CodeRoute.ts b/src/routes/CodeRoute.ts index c06babb..d49a55d 100644 --- a/src/routes/CodeRoute.ts +++ b/src/routes/CodeRoute.ts @@ -1,9 +1,9 @@ -import { Request, Response } from "express"; import bcrypt from "bcrypt"; +import { Request, Response } from "express"; import QRCode, { QRCodeToDataURLOptions } from "qrcode"; -import { TelegramID, VerificationString } from "../types"; -import { User, UserInstance } from "../db/models/User"; +import { UserInstance } from "../db/models/User"; import { getUserByTelegramID } from "../db/models/User.helper"; +import { TelegramID, VerificationString } from "../types"; export async function CodeRoute(req: Request, res: Response) { if (!req.session.userTelegramID) { diff --git a/src/routes/CovidRoute.ts b/src/routes/CovidRoute.ts index 9299fca..01b725f 100644 --- a/src/routes/CovidRoute.ts +++ b/src/routes/CovidRoute.ts @@ -3,6 +3,7 @@ import { getUserCovidPositivity, setUserCovidPositivity, } from "../db/models/User.helper"; +import { informContacts } from "../telegram"; interface CovidRouteRequest extends Request { body: { @@ -18,6 +19,7 @@ export async function CovidRoute(req: CovidRouteRequest, res: Response) { try { if (req.body.setPositive) { await setUserCovidPositivity(req.session.userTelegramID, true); + await informContacts(req.session.userTelegramID); res.send({ covidPositive: true }); } else { const isInfected = await getUserCovidPositivity( diff --git a/src/routes/LoginRoute.ts b/src/routes/LoginRoute.ts index c940910..020aa79 100644 --- a/src/routes/LoginRoute.ts +++ b/src/routes/LoginRoute.ts @@ -1,9 +1,8 @@ -import { Request, Response } from "express"; import crypto from "crypto"; -import { addContact, createUser } from "../db/utils"; -import { TelegramID, UserRowID } from "../types"; -import { User } from "../db/models/User"; -import { getUserByTelegramID } from "../db/models/User.helper"; +import { Request, Response } from "express"; +import { addContact } from "../db/models/Contact.helper"; +import { createUser, getUserByTelegramID } from "../db/models/User.helper"; +import { TelegramID } from "../types"; type TelegramLoginResponse = { id: TelegramID; diff --git a/src/routes/TelegramWebhookRoute.ts b/src/routes/TelegramWebhookRoute.ts index 3c1c3be..70863e1 100644 --- a/src/routes/TelegramWebhookRoute.ts +++ b/src/routes/TelegramWebhookRoute.ts @@ -1,10 +1,7 @@ import { Request, Response } from "express"; -import { Op } from "sequelize"; -import { Contact } from "../db/models/Contact"; -import { User } from "../db/models/User"; -import { getUserByRowID, getUserByTelegramID } from "../db/models/User.helper"; +import { getUserByTelegramID } from "../db/models/User.helper"; import { strings_en } from "../strings"; -import { sendTelegramMessage } from "../telegram"; +import { informContacts, sendTelegramMessage } from "../telegram"; import { TelegramID } from "../types"; interface TelegramWebhookRequest extends Request { @@ -50,26 +47,6 @@ export async function TelegramWebhookRoute( res.send(); } -async function informContacts(telegramID: TelegramID): Promise { - const user = await getUserByTelegramID(telegramID); - if (!user) throw new Error("User not found"); - const contacts = await Contact.findAll({ - where: { - [Op.or]: [{ user: user.id }, { with: user.id }], - }, - }); - - contacts.forEach(async (contact) => { - const otherPersonID = contact.user == user.id ? contact.with : contact.user; - const otherUser = await getUserByRowID(otherPersonID); - if (!otherUser) throw new Error("Other user does not exist"); - await sendTelegramMessage( - otherUser.telegram, - strings_en.telegram_inform_infect - ); - }); -} - async function userInfected(telegramID: TelegramID): Promise { const user = await getUserByTelegramID(telegramID); if (!user) throw new Error("User not found"); diff --git a/src/routes/VerifyRoute.ts b/src/routes/VerifyRoute.ts index 0197ab1..8ca693f 100644 --- a/src/routes/VerifyRoute.ts +++ b/src/routes/VerifyRoute.ts @@ -1,8 +1,7 @@ import { Request, Response } from "express"; -import { User } from "../db/models/User"; +import { addContact } from "../db/models/Contact.helper"; import { getUserByVerification } from "../db/models/User.helper"; -import { addContact } from "../db/utils"; -import { UserRowID, VerificationString } from "../types"; +import { VerificationString } from "../types"; interface VerifyRequest extends Request { body: { @@ -14,7 +13,7 @@ export async function VerifyRoute(req: VerifyRequest, res: Response) { const verifiedByUser = await getUserByVerification( decodeURIComponent(req.body.id) as VerificationString ); - try{ + try { if (!!verifiedByUser) { req.session.isVerified = !!verifiedByUser; req.session.verifiedByTelegramID = verifiedByUser.telegram; @@ -32,7 +31,7 @@ export async function VerifyRoute(req: VerifyRequest, res: Response) { } else { res.status(400).send({ success: false }); } - }catch(e){ - res.status(500).send({error: e instanceof Error ? e.message : "Error"}); + } catch (e) { + res.status(500).send({ error: e instanceof Error ? e.message : "Error" }); } } diff --git a/src/telegram.ts b/src/telegram.ts index 9cca20a..63dfbe7 100644 --- a/src/telegram.ts +++ b/src/telegram.ts @@ -1,4 +1,8 @@ import axios from "axios"; +import { Op } from "sequelize"; +import { Contact } from "./db/models/Contact"; +import { getUserByRowID, getUserByTelegramID } from "./db/models/User.helper"; +import { strings_en } from "./strings"; import { TelegramID } from "./types"; export async function setTelegramWebHook(): Promise { @@ -21,10 +25,27 @@ export async function sendTelegramMessage( }); } +export async function informContacts(telegramID: TelegramID): Promise { + const user = await getUserByTelegramID(telegramID); + if (!user) throw new Error("User not found"); + const contacts = await Contact.findAll({ + where: { + [Op.or]: [{ user: user.id }, { with: user.id }], + }, + }); -setTelegramWebHook() -.catch(error=>{ + contacts.forEach(async (contact) => { + const otherPersonID = contact.user == user.id ? contact.with : contact.user; + const otherUser = await getUserByRowID(otherPersonID); + if (!otherUser) throw new Error("Other user does not exist"); + await sendTelegramMessage( + otherUser.telegram, + strings_en.telegram_inform_infect + ); + }); +} + +setTelegramWebHook().catch((error) => { console.error("Error setting Telegram Webhook"); error instanceof Error && console.error(error.message); }); -