diff --git a/.gitignore b/.gitignore index be303de..52ebddf 100644 --- a/.gitignore +++ b/.gitignore @@ -117,3 +117,5 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* + +built/**/* \ No newline at end of file diff --git a/built/app.js b/built/app.js deleted file mode 100644 index 715dc67..0000000 --- a/built/app.js +++ /dev/null @@ -1,25 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const express = require("express"); -const session = require("express-session"); -const cors = require("cors"); -const session_1 = require("./session"); -const TelegramWebhookRoute_1 = require("./routes/TelegramWebhookRoute"); -const LoginRoute_1 = require("./routes/LoginRoute"); -const CodeRoute_1 = require("./routes/CodeRoute"); -const VerifyRoute_1 = require("./routes/VerifyRoute"); -require("dotenv-flow").config(); -console.log(`Node Environment: ${process.env.NODE_ENV}`); -const app = express(); -app.set("trust proxy", 1); -app.use(session(session_1.sessionOpts)); -app.use(cors(session_1.corsOpts)); -app.use(express.json()); -app.post(`/${process.env.TELEGRAM_SECRET}`, TelegramWebhookRoute_1.TelegramWebhookRoute); -app.post("/login", LoginRoute_1.LoginRoute); -app.get("/code", CodeRoute_1.CodeRoute); -app.post("/verify", VerifyRoute_1.VerifyRoute); -const port = process.env.PORT || 8080; -app.listen(port, () => { - console.log(`Listening on port ${port}`); -}); diff --git a/built/db/db.js b/built/db/db.js deleted file mode 100644 index c58ea90..0000000 --- a/built/db/db.js +++ /dev/null @@ -1,75 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.User = exports.Contact = exports.store = exports.storeDB = exports.sequelize = void 0; -const connect_session_sequelize_1 = __importDefault(require("connect-session-sequelize")); -const express_session_1 = __importDefault(require("express-session")); -const sequelize_1 = require("sequelize"); -const SequelizeStore = connect_session_sequelize_1.default(express_session_1.default.Store); -const isProduction = process.env.NODE_ENV == "production"; -exports.sequelize = (() => { - if (isProduction) { - return new sequelize_1.Sequelize(process.env.DB_DATA_NAME || "DATABASE", process.env.DB_USER || "USERNAME", process.env.DB_PASS || "PASSWORD", { - host: process.env.DB_PATH || "localhost", - dialect: "postgres", - }); - } - else { - return new sequelize_1.Sequelize("sqlite::memory:"); - } -})(); -exports.storeDB = (() => { - if (isProduction) { - return new sequelize_1.Sequelize(process.env.DB_STORE_NAME || "DATABASE", process.env.DB_USER || "USERNAME", process.env.DB_PASS || "PASSWORD", { - host: process.env.DB_PATH, - dialect: "postgres", - }); - } - else { - return new sequelize_1.Sequelize("sqlite::memory:"); - } -})(); -exports.store = new SequelizeStore({ - db: exports.storeDB, -}); -exports.Contact = exports.sequelize.define("Contact", { - user: { - type: sequelize_1.DataTypes.INTEGER, - allowNull: false, - }, - with: { - type: sequelize_1.DataTypes.INTEGER, - allowNull: false, - }, -}); -exports.User = exports.sequelize.define("User", { - id: { - type: sequelize_1.DataTypes.INTEGER, - autoIncrement: true, - primaryKey: true, - }, - telegram: { - type: sequelize_1.DataTypes.INTEGER, - allowNull: false, - unique: true, - }, - verification: { - type: sequelize_1.DataTypes.STRING, - }, - isInfected: { - type: sequelize_1.DataTypes.BOOLEAN, - }, -}); -exports.Contact.sync(); -exports.User.sync().then(() => { - if (process.env.ADMIN_USERNAME && process.env.ADMIN_PASSWORD) { - exports.User.create({ - telegram: 12345, - }).catch(() => { - console.log("Couldn't create admin account. Probably exists."); - }); - } -}); -exports.store.sync(); diff --git a/built/db/utils.js b/built/db/utils.js deleted file mode 100644 index 28ee01d..0000000 --- a/built/db/utils.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.createUser = exports.addContact = void 0; -const telegram_1 = require("../telegram"); -const db_1 = require("./db"); -function addContact(userATelegram, userBRowID, done) { - db_1.User.findOne({ where: { telegram: userATelegram } }).then((userA) => { - db_1.User.findOne({ where: { id: userBRowID } }).then((userB) => { - if (!!userA || !!userB) { - done(false, "Could not find user."); - return; - } - db_1.Contact.create({ user: userA.id, with: userBRowID }) - .then(() => { - console.log(`Registering contact between ${userA.id} and ${userBRowID}`); - telegram_1.sendTelegramMessage(userB.telegram, "Someone scanned your QR code. You will be notified if they are tested positive with Covid. If you are tested positive, please tell this bot /COVIDPOSITIVE"); - done(true, "Successfully added contact"); - }) - .catch((e) => { - done(false, e); - }); - }); - }); -} -exports.addContact = addContact; -function createUser(telegram, callback) { - db_1.User.create({ - telegram: telegram, - }) - .then((user) => { - if (!user) { - callback(false, "Could not create user"); - } - else { - callback(true, "Success"); - } - }) - .catch((reason) => { - if (reason.name == "SequelizeUniqueConstraintError") { - callback(false, "User already exists"); - } - else { - callback(false, "Unknown error"); - } - }); -} -exports.createUser = createUser; diff --git a/built/routes/CodeRoute.js b/built/routes/CodeRoute.js deleted file mode 100644 index 133c1e0..0000000 --- a/built/routes/CodeRoute.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.CodeRoute = void 0; -const db_1 = require("../db/db"); -const bcrypt_1 = __importDefault(require("bcrypt")); -const qrcode_1 = __importDefault(require("qrcode")); -function CodeRoute(req, res) { - if (!req.session.user) { - res.status(401).send("Not logged in"); - return; - } - createQRCode(req.session.user, (err, url) => { - res.status(url ? 200 : 401).send({ error: err, data: url }); - }); -} -exports.CodeRoute = CodeRoute; -function createQRCode(telegram, callback) { - db_1.User.findOne({ - where: { - telegram: telegram, - }, - }) - .then((user) => { - user && - refreshVerification(user, (result) => { - const verifyURL = `${process.env.WEBSITE_URL}/#/verify/${encodeURIComponent(result.verification)}`; - qrcode_1.default.toDataURL(verifyURL, { width: 300, height: 300 }, (error, url) => { - callback(error.message, url); - }); - }); - }) - .catch((error) => { - callback(error); - }); -} -function refreshVerification(user, callback) { - let newVerification = bcrypt_1.default - .hashSync(`${new Date().getTime()}-${user.telegram}`, 5) - .replace(/[^a-zA-Z0-9]+/g, ""); - newVerification = newVerification.substr(0, newVerification.length / 2); - user.verification = newVerification; - user.save().then((result) => { - callback(result); - }); -} diff --git a/built/routes/LoginRoute.js b/built/routes/LoginRoute.js deleted file mode 100644 index 35e8694..0000000 --- a/built/routes/LoginRoute.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.LoginRoute = void 0; -const db_1 = require("../db/db"); -const crypto_1 = __importDefault(require("crypto")); -const utils_1 = require("../db/utils"); -function LoginRoute(req, res) { - const telegramResponse = req.body.telegramResponse; - authUser(telegramResponse, (authObject) => { - if (authObject) { - const verified = req.session.verified; - const verifiedBy = req.session.verifiedBy; - req.session.regenerate(() => { - req.session.user = telegramResponse.id; - if (verified) { - utils_1.addContact(telegramResponse.id, verifiedBy, (contactSuccess) => { - res.send({ - authorized: authObject.authorized, - contactSuccess: contactSuccess, - }); - }); - } - else { - res.send(authObject); - } - }); - } - else { - res.status(401).send(authObject); - } - }); -} -exports.LoginRoute = LoginRoute; -function authUser(telegramResponse, callback) { - let dataCheckArray = []; - for (const [key, value] of Object.entries(telegramResponse)) { - if (key == "hash") - continue; - dataCheckArray.push(`${key}=${value}`); - } - dataCheckArray.sort(); - const dataCheckString = dataCheckArray.join("\n"); - const secretKey = crypto_1.default - .createHash("sha256") - .update(process.env.TELEGRAM_TOKEN) - .digest(); - const confirmationHash = crypto_1.default - .createHmac("sha256", secretKey) - .update(dataCheckString) - .digest("hex"); - const authorized = confirmationHash == telegramResponse.hash; - if (!authorized) { - callback({ authorized: false }); - } - db_1.User.findOne({ - where: { - telegram: telegramResponse.id, - }, - }).then((user) => { - if (!user) { - utils_1.createUser(telegramResponse.id, (success) => { - callback({ authorized: success }); - }); - } - else { - callback({ authorized: true }); - } - }); -} -exports.LoginRoute = LoginRoute; diff --git a/built/routes/TelegramWebhookRoute.js b/built/routes/TelegramWebhookRoute.js deleted file mode 100644 index 8054f69..0000000 --- a/built/routes/TelegramWebhookRoute.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.TelegramWebhookRoute = void 0; -const types_1 = require("sequelize/types"); -const db_1 = require("../db/db"); -const telegram_1 = require("../telegram"); -function TelegramWebhookRoute(req, res) { - try { - const messageText = req.body.message.text; - const telegramID = req.body.message.from.id; - if (messageText.toLowerCase() == "/covidpositive") { - userInfected(telegramID, (result) => { - if (result.saved) { - telegram_1.sendTelegramMessage(telegramID, "Thanks for informing us. We will notify the people you were in contact with!"); - informContacts(telegramID); - } - else { - telegram_1.sendTelegramMessage(telegramID, "Sorry, something went wrong."); - } - }); - } - } - catch (e) { - console.log("Could not get Telegram Message"); - } - res.send(); -} -exports.TelegramWebhookRoute = TelegramWebhookRoute; -function informContacts(telegramID) { - db_1.User.findOne({ - where: { - telegram: telegramID, - }, - }).then((user) => { - if (user) { - const userRowID = user.id; - db_1.Contact.findAll({ - where: { - [types_1.Op.or]: [{ user: userRowID }, { with: userRowID }], - }, - }).then((result) => { - result.forEach((contact) => { - const otherPersonID = contact.user == userRowID ? contact.with : contact.user; - db_1.User.findOne({ - where: { - id: otherPersonID, - }, - }).then((otherPerson) => { - otherPerson && - telegram_1.sendTelegramMessage(otherPerson.telegram, "You're infected."); - }); - }); - }); - } - }); -} -function userInfected(telegramID, callback) { - db_1.User.findOne({ - where: { - telegram: telegramID, - }, - }) - .then((user) => { - if (!user) { - callback({ saved: false }); - } - else { - user.isInfected = true; - user - .save() - .then((result) => { - if (result) { - callback({ saved: true }); - } - }) - .catch((err) => { - callback({ saved: false }); - }); - } - }) - .catch((err) => { - callback({ saved: false }); - }); -} diff --git a/built/routes/VerifyRoute.js b/built/routes/VerifyRoute.js deleted file mode 100644 index b60b088..0000000 --- a/built/routes/VerifyRoute.js +++ /dev/null @@ -1,44 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.VerifyRoute = void 0; -const db_1 = require("../db/db"); -const utils_1 = require("../db/utils"); -function VerifyRoute(req, res) { - checkVerification(req.body.id, (success, msg, withUserID) => { - if (success) { - req.session.verified = success; - req.session.verifiedBy = withUserID; - if (req.session.user) { - // If Logged In - utils_1.addContact(req.session.user, withUserID, (success, msg) => { - res - .status(success ? 200 : 400) - .send({ success: success, message: msg, loggedIn: true }); - }); - } - else { - // If Not Logged In - res.send({ success: success, message: msg, loggedIn: false }); - } - } - else { - res.status(400).send({ success: success, message: msg }); - } - }); -} -exports.VerifyRoute = VerifyRoute; -function checkVerification(verification, callback) { - db_1.User.findOne({ - where: { - verification: decodeURIComponent(verification), - }, - }).then((user) => { - if (user) { - callback(true, "User verified", user.id); - } - else { - callback(false, "No such verification"); - } - }); -} -exports.VerifyRoute = VerifyRoute; diff --git a/built/session.js b/built/session.js deleted file mode 100644 index 7b19ef2..0000000 --- a/built/session.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.corsOpts = exports.sessionOpts = void 0; -const db_1 = require("./db/db"); -exports.sessionOpts = { - secret: process.env.SERVER_SESSION_SECRET, - resave: false, - saveUninitialized: false, - cookie: { - secure: true, - sameSite: "none", - maxAge: Number(process.env.SESSION_LENGTH), - }, - store: db_1.store, -}; -exports.corsOpts = { credentials: true, origin: true, secure: true }; diff --git a/built/telegram.js b/built/telegram.js deleted file mode 100644 index 9b1014c..0000000 --- a/built/telegram.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.sendTelegramMessage = exports.setTelegramWebHook = void 0; -const axios_1 = __importDefault(require("axios")); -function setTelegramWebHook(callback = () => { }) { - const url = `https://api.telegram.org/bot${process.env.TELEGRAM_TOKEN}/setWebhook`; - axios_1.default - .post(url, { - url: `${process.env.SERVER_API_URL}/${process.env.TELEGRAM_SECRET}`, - allowed_updates: [], - drop_pending_updates: true, - }) - .then((res) => { - callback(!!res); - }) - .catch((err) => { - callback(!!err); - }); -} -exports.setTelegramWebHook = setTelegramWebHook; -function sendTelegramMessage(telegramID, message, callback = () => { }) { - const url = `https://api.telegram.org/bot${process.env.TELEGRAM_TOKEN}/sendMessage`; - axios_1.default - .post(url, { - chat_id: telegramID, - text: message, - }) - .then((res) => { - callback(!!res); - }) - .catch((err) => { - console.error("Problem sending Telegram message."); - callback(!!err); - }); -} -exports.sendTelegramMessage = sendTelegramMessage; -setTelegramWebHook(); diff --git a/built/utils.js b/built/utils.js deleted file mode 100644 index ce4af57..0000000 --- a/built/utils.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getCookieExpiry = void 0; -function getCookieExpiry() { - return new Date(Date.now() + Number(process.env.COOKIE_EXPIRY_DURATION)); -} -exports.getCookieExpiry = getCookieExpiry; diff --git a/src/routes/TelegramWebhookRoute.ts b/src/routes/TelegramWebhookRoute.ts index f33c9e7..983b9ee 100644 --- a/src/routes/TelegramWebhookRoute.ts +++ b/src/routes/TelegramWebhookRoute.ts @@ -1,5 +1,5 @@ import { Request, Response } from "express"; -import { Op } from "sequelize/types"; +import { Op } from "sequelize"; import { Contact, TelegramID, User } from "../db/db"; import { strings_en } from "../strings"; import { sendTelegramMessage } from "../telegram";