login.mjs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { chromium } from "playwright";
  2. import uniqueRandomArray from "unique-random-array";
  3. import userAgents from "top-user-agents";
  4. import { dirname, resolve, join } from "path";
  5. import { fileURLToPath } from "url";
  6. import fs from "fs";
  7. import stringHash from "string-hash";
  8. const __filename = fileURLToPath(import.meta.url);
  9. const __dirname = dirname(__filename);
  10. export async function login(email, password, proxy) {
  11. const browser = await chromium.launch({
  12. headless: true,
  13. devtools: false,
  14. });
  15. const options = {
  16. userAgent: uniqueRandomArray(userAgents)(),
  17. viewport: {
  18. width: parseInt(Math.random() * 100 + 1250),
  19. height: parseInt(Math.random() * 100 + 750),
  20. },
  21. locale: "en-CA",
  22. timezoneId: "America/Toronto",
  23. serviceWorkers: "block",
  24. };
  25. if (proxy) {
  26. options.proxy = proxy;
  27. }
  28. const context = await browser.newContext(options);
  29. const page = await context.newPage();
  30. let points = null;
  31. await context.route(/points$/, async (route, request) => {
  32. const response = await route.fetch();
  33. points = await response.text();
  34. await route.continue();
  35. });
  36. await context.route(
  37. /(\.png)|(\.jpg)|(\.svg)|(\.otf)|(\.woff)|(\.woff2)|(\.ttf)|(\.mp3)/,
  38. (route, request) => route.abort()
  39. );
  40. await context.route(/(\.js)|(\.css)/, async (route, request) => {
  41. const fileName = resolve(
  42. __dirname,
  43. "cache",
  44. "" + stringHash(request.url())
  45. );
  46. if (fs.existsSync(fileName)) {
  47. await route.fulfill({
  48. body: fs.readFileSync(fileName),
  49. contentType: /\.js$/.test(request.url())
  50. ? "application/javascript"
  51. : "text/css",
  52. });
  53. } else {
  54. const response = await route.fetch();
  55. fs.writeFileSync(fileName, await response.body());
  56. await route.fulfill({
  57. response,
  58. });
  59. }
  60. });
  61. await page.goto("https://www.pcoptimum.ca/");
  62. const link = await page.$('a > span:has-text("sign in")');
  63. link.click();
  64. await page.waitForURL("https://accounts.pcid.ca/login");
  65. await page.fill('input[id="email"]', email);
  66. await page.fill('input[id="password"]', password);
  67. try {
  68. await new Promise(async (resolve, reject) => {
  69. await page.route(/\/login$/, async (route, request) => {
  70. console.log(
  71. `${request.method()} ${request.resourceType()} ${request.url()}`
  72. );
  73. if (request.method() === "POST") {
  74. const response = await route.fetch();
  75. const status = response.status();
  76. console.log(status);
  77. if (status === 200) {
  78. await route.continue();
  79. resolve();
  80. } else if (status === 401) {
  81. reject(new Error("Invalid email or password"));
  82. } else if (status === 429) {
  83. reject(
  84. new Error(
  85. "Oops, something went wrong. Please try again later."
  86. )
  87. );
  88. } else {
  89. reject(
  90. new Error("Unknown error. Please try again later.")
  91. );
  92. }
  93. } else {
  94. await route.continue();
  95. }
  96. });
  97. await page.click('button:has-text("Sign in")');
  98. });
  99. } catch (error) {
  100. await browser.close();
  101. throw error;
  102. }
  103. try {
  104. await page.waitForURL("https://www.pcoptimum.ca/dashboard");
  105. for (let i = 0; i < 30; i++) {
  106. await page.waitForTimeout(1000);
  107. if (points) break;
  108. }
  109. } catch (error) {
  110. console.error(error.stack);
  111. }
  112. let cookies = null;
  113. try {
  114. cookies = JSON.stringify(await context.cookies());
  115. } catch (error) {}
  116. await browser.close();
  117. return { points, cookies, options };
  118. }