@ubaidbinwaris/linkedin 1.1.1 → 1.1.4
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/package.json +1 -1
- package/src/auth/checkpoint.js +43 -1
- package/src/login/login.js +44 -5
package/package.json
CHANGED
package/src/auth/checkpoint.js
CHANGED
|
@@ -28,4 +28,46 @@ async function detectCheckpoint(page) {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Handles mobile verification/app approval prompts.
|
|
33
|
+
* Polls for success (feed navigation) for a set duration.
|
|
34
|
+
* @param {Page} page
|
|
35
|
+
* @returns {Promise<boolean>} true if resolved, false if timed out/failed
|
|
36
|
+
*/
|
|
37
|
+
async function handleMobileVerification(page) {
|
|
38
|
+
try {
|
|
39
|
+
const isMobileVerif = await page.evaluate(() => {
|
|
40
|
+
const text = document.body.innerText;
|
|
41
|
+
// User checks: "Check your LinkedIn app", "Open your LinkedIn app", "Approve the sign-in"
|
|
42
|
+
return text.includes("Check your LinkedIn app") ||
|
|
43
|
+
text.includes("Open your LinkedIn app") ||
|
|
44
|
+
text.includes("Tap Yes on the prompt") ||
|
|
45
|
+
text.includes("verification request to your device") ||
|
|
46
|
+
text.includes("Approve the sign-in");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (!isMobileVerif) return false;
|
|
50
|
+
|
|
51
|
+
logger.warn("ACTION REQUIRED: Check your LinkedIn app on your phone! Waiting 2 minutes...");
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// Poll for feed URL for 120 seconds
|
|
55
|
+
await page.waitForFunction(() => {
|
|
56
|
+
return window.location.href.includes("/feed") ||
|
|
57
|
+
document.querySelector('.global-nav__search');
|
|
58
|
+
}, { timeout: 120000 });
|
|
59
|
+
|
|
60
|
+
logger.info("Mobile verification successful! Resuming...");
|
|
61
|
+
return true; // Resolved
|
|
62
|
+
} catch (timeoutErr) {
|
|
63
|
+
logger.warn("Mobile verification timed out (No approval detected).");
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
} catch (e) {
|
|
68
|
+
logger.warn(`Mobile verification check failed: ${e.message}`);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = { detectCheckpoint, handleMobileVerification };
|
package/src/login/login.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const logger = require("../utils/logger");
|
|
2
2
|
const { saveSession, SessionLock } = require("../session/sessionManager");
|
|
3
3
|
const { createBrowser, createContext } = require("../browser/launcher");
|
|
4
|
-
const { detectCheckpoint } = require("../auth/checkpoint");
|
|
4
|
+
const { detectCheckpoint, handleMobileVerification } = require("../auth/checkpoint");
|
|
5
5
|
const { performCredentialLogin, isLoggedIn } = require("../auth/actions");
|
|
6
6
|
const { randomDelay } = require("../utils/time");
|
|
7
7
|
|
|
@@ -68,10 +68,49 @@ async function loginToLinkedIn(options = {}, credentials = null) {
|
|
|
68
68
|
// STEP 4: Verify & Fail Fast
|
|
69
69
|
// ----------------------------
|
|
70
70
|
if (await detectCheckpoint(page)) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
// Attempt to handle mobile verification (2 min wait)
|
|
72
|
+
// If it returns true, it means we are now on the feed (resolved)
|
|
73
|
+
if (await handleMobileVerification(page)) {
|
|
74
|
+
// success, assume logged in
|
|
75
|
+
} else {
|
|
76
|
+
// Failed mobile verification.
|
|
77
|
+
// User Request: "otherwise after some delay using browser opens the browser and fill the form"
|
|
78
|
+
|
|
79
|
+
if (options.headless) {
|
|
80
|
+
logger.info("[Fallback] Mobile verification failed. Switching to VISIBLE browser for manual intervention...");
|
|
81
|
+
await browser.close();
|
|
82
|
+
|
|
83
|
+
// RE-LAUNCH in Visible Mode
|
|
84
|
+
const visibleBrowser = await createBrowser({ ...options, headless: false });
|
|
85
|
+
const visibleContext = await createContext(visibleBrowser, email);
|
|
86
|
+
const visiblePage = await visibleContext.newPage();
|
|
87
|
+
visiblePage.setDefaultTimeout(60000); // More time for manual interaction
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
logger.info("[Fallback] Filling credentials in visible browser...");
|
|
91
|
+
await performCredentialLogin(visiblePage, email, password);
|
|
92
|
+
|
|
93
|
+
// Now wait for success (Feed)
|
|
94
|
+
logger.info("[Fallback] Waiting for user to complete login manually...");
|
|
95
|
+
await visiblePage.waitForSelector(".global-nav__search", { timeout: 120000 });
|
|
96
|
+
|
|
97
|
+
if (await isLoggedIn(visiblePage)) {
|
|
98
|
+
logger.info(`[${email}] Manual Fallback Successful ✅`);
|
|
99
|
+
await saveSession(visibleContext, email, true);
|
|
100
|
+
return { browser: visibleBrowser, context: visibleContext, page: visiblePage };
|
|
101
|
+
}
|
|
102
|
+
} catch (fallbackErr) {
|
|
103
|
+
logger.error(`[Fallback] Manual intervention failed or timed out: ${fallbackErr.message}`);
|
|
104
|
+
await visibleBrowser.close();
|
|
105
|
+
throw new Error("CHECKPOINT_DETECTED_M"); // M for manual failed
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const screenshotPath = `checkpoint_${email}_${Date.now()}.png`;
|
|
110
|
+
await page.screenshot({ path: screenshotPath });
|
|
111
|
+
logger.warn(`[${email}] Checkpoint detected! Screenshot saved: ${screenshotPath}`);
|
|
112
|
+
throw new Error("CHECKPOINT_DETECTED");
|
|
113
|
+
}
|
|
75
114
|
}
|
|
76
115
|
|
|
77
116
|
if (await isLoggedIn(page)) {
|