@thetypefounders/continue-with-google 1.0.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,9 +11,9 @@ npm install @thetypefounders/continue-with-google --save
11
11
  ## Usage
12
12
 
13
13
  ```javascript
14
+ import { authenticate } from '@thetypefounders/continue-with-google';
14
15
  import Puppeteer from 'puppeteer-extra';
15
16
  import StealthPlugin from 'puppeteer-extra-plugin-stealth';
16
- import { authenticate } from '@thetypefounders/continue-with-google';
17
17
 
18
18
  Puppeteer.use(StealthPlugin());
19
19
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,13 @@
1
- import { type ElementHandle, Page } from 'puppeteer';
1
+ import { type ElementHandle, Page, WaitForSelectorOptions } from 'puppeteer';
2
2
  export interface Logger {
3
3
  info(message: string): void;
4
+ warn(message: string): void;
4
5
  }
5
- export declare function authenticate(page: Page, email: string, password: string, secret: string, target: string, logger?: Logger, attemptCount?: number, attemptSeconds?: number): Promise<ElementHandle | null>;
6
+ export type Options = {
7
+ challengeCount?: number;
8
+ challengeTimeoutSeconds?: number;
9
+ trialCount?: number;
10
+ trialTimeoutSeconds?: number;
11
+ waitForSelector?: WaitForSelectorOptions;
12
+ };
13
+ export declare function authenticate(page: Page, email: string, password: string, secret: string, selector: string, options?: Options, logger?: Logger): Promise<ElementHandle | null>;
package/dist/index.js CHANGED
@@ -1,6 +1,12 @@
1
1
  import { generateToken } from 'authenticator';
2
2
  import { setTimeout } from 'node:timers/promises';
3
- export async function authenticate(page, email, password, secret, target, logger = console, attemptCount = 3, attemptSeconds = 30) {
3
+ const DEFAULTS = {
4
+ challengeCount: 3,
5
+ challengeTimeoutSeconds: 30,
6
+ trialCount: 10,
7
+ trialTimeoutSeconds: 2,
8
+ };
9
+ export async function authenticate(page, email, password, secret, selector, options = DEFAULTS, logger = console) {
4
10
  logger.info('Waiting to enter the email...');
5
11
  await page.waitForSelector('input[type=email]', { visible: true });
6
12
  logger.info('Entering the email...');
@@ -11,11 +17,13 @@ export async function authenticate(page, email, password, secret, target, logger
11
17
  logger.info('Entering the password...');
12
18
  await page.type('input[type=password]', password);
13
19
  await page.keyboard.press('Enter');
14
- for (let attempt = 0, found = false; attempt < attemptCount && !found; attempt++) {
20
+ for (let attempt = 0, found = false; attempt < (options.challengeCount || DEFAULTS.challengeCount) && !found; attempt++) {
15
21
  if (attempt > 0) {
16
22
  logger.info(`Challenged on attempt ${attempt}. Entering the code...`);
17
23
  if (attempt > 1) {
18
- await setTimeout(1000 * attemptSeconds);
24
+ await setTimeout(1000 *
25
+ (options.challengeTimeoutSeconds ||
26
+ DEFAULTS.challengeTimeoutSeconds));
19
27
  }
20
28
  const code = generateToken(secret);
21
29
  await page.evaluate(() => {
@@ -24,30 +32,33 @@ export async function authenticate(page, email, password, secret, target, logger
24
32
  });
25
33
  await page.type('input[type=tel]', code);
26
34
  await page.keyboard.press('Enter');
27
- await waitForPeace(page, logger);
35
+ await waitForTrial(page, options.trialCount || DEFAULTS.trialCount, options.trialTimeoutSeconds || DEFAULTS.trialTimeoutSeconds, logger);
28
36
  }
29
37
  found = await Promise.any([
30
- page.waitForSelector(target).then(() => true),
38
+ page.waitForSelector(selector, options.waitForSelector).then(() => true),
31
39
  page
32
40
  .waitForSelector('input[type=tel]', { visible: true })
33
41
  .then(() => false),
34
42
  ]);
35
43
  }
36
- return await page.$(target);
44
+ return await page.$(selector);
37
45
  }
38
- async function waitForPeace(page, logger, attemptCount = 10, attemptSeconds = 2) {
46
+ async function waitForTrial(page, attemptCount, attemptTimeoutSeconds, logger) {
39
47
  for (let attempt = -1, previous = undefined, current = undefined; attempt < attemptCount && (current === undefined || previous !== current); attempt++) {
40
48
  if (attempt > 0) {
41
- logger.info(`Changed on attempt ${attempt}. Taking a screenshot...`);
49
+ logger.info(`Tried on attempt ${attempt}. Taking a screenshot...`);
42
50
  }
43
51
  if (attempt > -1) {
44
- await setTimeout(1000 * attemptSeconds);
52
+ await setTimeout(1000 * attemptTimeoutSeconds);
45
53
  }
46
54
  const future = await screenshot(page);
47
55
  if (future) {
48
56
  previous = current;
49
57
  current = future;
50
58
  }
59
+ else {
60
+ logger.warn(`Failed to take a screenshot.`);
61
+ }
51
62
  }
52
63
  }
53
64
  async function screenshot(page) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thetypefounders/continue-with-google",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Ivan Ukhov <ivan.ukhov@gmail.com>",
6
6
  "description": "Two-factor authentication with Google via Puppeteer",
package/src/index.ts CHANGED
@@ -1,20 +1,35 @@
1
1
  import { generateToken } from 'authenticator';
2
2
  import { setTimeout } from 'node:timers/promises';
3
- import { type ElementHandle, Page } from 'puppeteer';
3
+ import { type ElementHandle, Page, WaitForSelectorOptions } from 'puppeteer';
4
4
 
5
5
  export interface Logger {
6
6
  info(message: string): void;
7
+ warn(message: string): void;
7
8
  }
8
9
 
10
+ export type Options = {
11
+ challengeCount?: number;
12
+ challengeTimeoutSeconds?: number;
13
+ trialCount?: number;
14
+ trialTimeoutSeconds?: number;
15
+ waitForSelector?: WaitForSelectorOptions;
16
+ };
17
+
18
+ const DEFAULTS: Options = {
19
+ challengeCount: 3,
20
+ challengeTimeoutSeconds: 30,
21
+ trialCount: 10,
22
+ trialTimeoutSeconds: 2,
23
+ };
24
+
9
25
  export async function authenticate(
10
26
  page: Page,
11
27
  email: string,
12
28
  password: string,
13
29
  secret: string,
14
- target: string,
15
- logger: Logger = console,
16
- attemptCount: number = 3,
17
- attemptSeconds: number = 30
30
+ selector: string,
31
+ options: Options = DEFAULTS,
32
+ logger: Logger = console
18
33
  ): Promise<ElementHandle | null> {
19
34
  logger.info('Waiting to enter the email...');
20
35
  await page.waitForSelector('input[type=email]', { visible: true });
@@ -30,13 +45,17 @@ export async function authenticate(
30
45
 
31
46
  for (
32
47
  let attempt = 0, found = false;
33
- attempt < attemptCount && !found;
48
+ attempt < (options.challengeCount || DEFAULTS.challengeCount!) && !found;
34
49
  attempt++
35
50
  ) {
36
51
  if (attempt > 0) {
37
52
  logger.info(`Challenged on attempt ${attempt}. Entering the code...`);
38
53
  if (attempt > 1) {
39
- await setTimeout(1000 * attemptSeconds);
54
+ await setTimeout(
55
+ 1000 *
56
+ (options.challengeTimeoutSeconds ||
57
+ DEFAULTS.challengeTimeoutSeconds!)
58
+ );
40
59
  }
41
60
  const code = generateToken(secret);
42
61
  await page.evaluate(() => {
@@ -45,24 +64,29 @@ export async function authenticate(
45
64
  });
46
65
  await page.type('input[type=tel]', code);
47
66
  await page.keyboard.press('Enter');
48
- await waitForPeace(page, logger);
67
+ await waitForTrial(
68
+ page,
69
+ options.trialCount || DEFAULTS.trialCount!,
70
+ options.trialTimeoutSeconds || DEFAULTS.trialTimeoutSeconds!,
71
+ logger
72
+ );
49
73
  }
50
74
  found = await Promise.any([
51
- page.waitForSelector(target).then(() => true),
75
+ page.waitForSelector(selector, options.waitForSelector).then(() => true),
52
76
  page
53
77
  .waitForSelector('input[type=tel]', { visible: true })
54
78
  .then(() => false),
55
79
  ]);
56
80
  }
57
81
 
58
- return await page.$(target);
82
+ return await page.$(selector);
59
83
  }
60
84
 
61
- async function waitForPeace(
85
+ async function waitForTrial(
62
86
  page: Page,
63
- logger: Logger,
64
- attemptCount: number = 10,
65
- attemptSeconds: number = 2
87
+ attemptCount: number,
88
+ attemptTimeoutSeconds: number,
89
+ logger: Logger
66
90
  ): Promise<void> {
67
91
  for (
68
92
  let attempt = -1, previous = undefined, current = undefined;
@@ -70,15 +94,17 @@ async function waitForPeace(
70
94
  attempt++
71
95
  ) {
72
96
  if (attempt > 0) {
73
- logger.info(`Changed on attempt ${attempt}. Taking a screenshot...`);
97
+ logger.info(`Tried on attempt ${attempt}. Taking a screenshot...`);
74
98
  }
75
99
  if (attempt > -1) {
76
- await setTimeout(1000 * attemptSeconds);
100
+ await setTimeout(1000 * attemptTimeoutSeconds);
77
101
  }
78
102
  const future = await screenshot(page);
79
103
  if (future) {
80
104
  previous = current;
81
105
  current = future;
106
+ } else {
107
+ logger.warn(`Failed to take a screenshot.`);
82
108
  }
83
109
  }
84
110
  }