start.mjs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import Vorpal from "vorpal";
  2. import { chromium } from "playwright";
  3. import os from "os";
  4. import fs from "fs";
  5. import path from "path";
  6. import { fileURLToPath } from "url";
  7. const __dirname = path.dirname(fileURLToPath(import.meta.url));
  8. console.log(__dirname);
  9. const vorpal = new Vorpal();
  10. const contexts = {};
  11. vorpal
  12. .command("new <name>")
  13. .alias("n")
  14. .action(async function (args, cb) {
  15. if (contexts[args.name]) {
  16. this.log("Context already exists");
  17. return cb();
  18. }
  19. function formatCookies(cookies) {
  20. return cookies.map((i) => {
  21. switch (i.sameSite) {
  22. case "no_restriction":
  23. case "None":
  24. i.sameSite = "None";
  25. break;
  26. case "lax":
  27. case "Lax":
  28. i.sameSite = "Lax";
  29. break;
  30. case "strict":
  31. case "Strict":
  32. i.sameSite = "Strict";
  33. break;
  34. default:
  35. i.sameSite = undefined;
  36. break;
  37. }
  38. return i;
  39. });
  40. }
  41. const userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), "myapp"));
  42. const pathToExtension = path.join(
  43. __dirname,
  44. "fngmhnnpilhplaeedifhccceomclgfbg"
  45. );
  46. // 启动浏览器
  47. const context = await chromium.launchPersistentContext(userDataDir, {
  48. headless: false,
  49. // proxy: {
  50. // server: "199.188.92.93:8000",
  51. // username: "proxy",
  52. // password: "rPZHv9U",
  53. // },
  54. args: [
  55. `--disable-extensions-except=${pathToExtension}`,
  56. `--load-extension=${pathToExtension}`,
  57. "--window-position=-1280,0",
  58. ],
  59. userAgent:
  60. "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3105.3 Safari/537.36",
  61. });
  62. let accountInfo;
  63. try {
  64. accountInfo = JSON.parse(
  65. fs
  66. .readFileSync(
  67. path.join(
  68. __dirname,
  69. "validAccounts",
  70. `${args.name}.json`
  71. )
  72. )
  73. .toString()
  74. );
  75. context.addCookies(accountInfo.cookies);
  76. } catch (error) {
  77. this.log("accountInfo not found");
  78. return;
  79. }
  80. contexts[args.name] = context;
  81. context.on("page", (page) => {
  82. vorpal.log("New page created");
  83. page.on("close", async () => {
  84. vorpal.log("Page closed");
  85. accountInfo.cookies = await page.context().cookies();
  86. fs.writeFileSync(
  87. path.join(__dirname, "validAccounts", `${args.name}.json`),
  88. JSON.stringify(accountInfo, null, 4)
  89. );
  90. });
  91. });
  92. context.on("close", () => {
  93. vorpal.log("Context closed");
  94. delete contexts[args.name];
  95. });
  96. // 创建一个新的浏览器页面
  97. const page = await context.newPage();
  98. page.goto("https://www.paypal.com/myaccount/summary");
  99. cb();
  100. });
  101. vorpal
  102. .command("close [name]")
  103. .alias("c")
  104. .option("-a, --all", "Close all contexts")
  105. .validate(function (args) {
  106. if (Object.keys(contexts).length === 0) {
  107. return "No context to close";
  108. }
  109. if (args.options.all && args.name) {
  110. return "Cannot use --all and a context name at the same time";
  111. }
  112. if (
  113. !args.options.all &&
  114. !args.name &&
  115. !Object.keys(contexts).length === 1
  116. ) {
  117. return "You must specify a context name or use --all";
  118. }
  119. return true;
  120. })
  121. .action(async function (args, cb) {
  122. this.log(args);
  123. if (args.options.all) {
  124. for (const name of Object.keys(contexts)) {
  125. await contexts[name].close();
  126. delete contexts[name];
  127. }
  128. } else if (args.name) {
  129. if (!contexts[args.name]) {
  130. this.log.error("Context not found");
  131. return cb();
  132. }
  133. await contexts[args.name].close();
  134. delete contexts[args.name];
  135. } else if (Object.keys(contexts).length === 1) {
  136. const name = Object.keys(contexts)[0];
  137. await contexts[name].close();
  138. delete contexts[name];
  139. }
  140. });
  141. vorpal.delimiter("myapp$").show();