feat: auto-refresh Kernel Managed Auth session on login failure — ensureLoggedIn() with retry
This commit is contained in:
@@ -19,6 +19,7 @@ import { sendTelegram, formatSearchSummary } from './lib/notify.mjs';
|
|||||||
import { DEFAULT_FIRST_RUN_DAYS } from './lib/constants.mjs';
|
import { DEFAULT_FIRST_RUN_DAYS } from './lib/constants.mjs';
|
||||||
import { generateKeywords } from './lib/keywords.mjs';
|
import { generateKeywords } from './lib/keywords.mjs';
|
||||||
import { initProgress, isCompleted, markComplete } from './lib/search_progress.mjs';
|
import { initProgress, isCompleted, markComplete } from './lib/search_progress.mjs';
|
||||||
|
import { ensureLoggedIn } from './lib/session.mjs';
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const lock = acquireLock('searcher', resolve(__dir, 'data'));
|
const lock = acquireLock('searcher', resolve(__dir, 'data'));
|
||||||
@@ -96,7 +97,7 @@ async function main() {
|
|||||||
let liBrowser;
|
let liBrowser;
|
||||||
try {
|
try {
|
||||||
liBrowser = await createBrowser(settings, 'linkedin');
|
liBrowser = await createBrowser(settings, 'linkedin');
|
||||||
const loggedIn = await liLogin(liBrowser.page);
|
const loggedIn = await ensureLoggedIn(liBrowser.page, liLogin, 'linkedin', settings.kernel_api_key || process.env.KERNEL_API_KEY);
|
||||||
if (!loggedIn) throw new Error('LinkedIn not logged in');
|
if (!loggedIn) throw new Error('LinkedIn not logged in');
|
||||||
console.log(' ✅ Logged in');
|
console.log(' ✅ Logged in');
|
||||||
|
|
||||||
@@ -135,7 +136,7 @@ async function main() {
|
|||||||
let wfBrowser;
|
let wfBrowser;
|
||||||
try {
|
try {
|
||||||
wfBrowser = await createBrowser(settings, 'wellfound');
|
wfBrowser = await createBrowser(settings, 'wellfound');
|
||||||
const loggedIn = await wfLogin(wfBrowser.page);
|
const loggedIn = await ensureLoggedIn(wfBrowser.page, wfLogin, 'wellfound', settings.kernel_api_key || process.env.KERNEL_API_KEY);
|
||||||
if (!loggedIn) console.warn(' ⚠️ Wellfound login unconfirmed, proceeding');
|
if (!loggedIn) console.warn(' ⚠️ Wellfound login unconfirmed, proceeding');
|
||||||
else console.log(' ✅ Logged in');
|
else console.log(' ✅ Logged in');
|
||||||
|
|
||||||
|
|||||||
67
lib/session.mjs
Normal file
67
lib/session.mjs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* session.mjs — Kernel Managed Auth session refresh
|
||||||
|
* Call refreshSession() before creating a browser to ensure the profile is fresh
|
||||||
|
*/
|
||||||
|
import { createRequire } from 'module';
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
|
const KERNEL_SDK_PATH = '/home/ubuntu/.openclaw/workspace/node_modules/@onkernel/sdk/index.js';
|
||||||
|
|
||||||
|
const CONNECTION_IDS = {
|
||||||
|
linkedin: 'REDACTED_CONNECTION_ID_LINKEDIN',
|
||||||
|
wellfound: 'REDACTED_CONNECTION_ID_WELLFOUND',
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function refreshSession(platform, apiKey) {
|
||||||
|
const connectionId = CONNECTION_IDS[platform];
|
||||||
|
if (!connectionId) throw new Error(`No connection ID for platform: ${platform}`);
|
||||||
|
|
||||||
|
const Kernel = require(KERNEL_SDK_PATH);
|
||||||
|
const kernel = new Kernel({ apiKey });
|
||||||
|
|
||||||
|
console.log(` 🔄 Refreshing ${platform} session...`);
|
||||||
|
|
||||||
|
// Trigger re-auth (uses stored credentials automatically)
|
||||||
|
const loginResp = await kernel.auth.connections.login(connectionId);
|
||||||
|
|
||||||
|
if (loginResp.status === 'SUCCESS') {
|
||||||
|
console.log(` ✅ ${platform} session refreshed`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not immediately successful, poll for up to 30s
|
||||||
|
const start = Date.now();
|
||||||
|
while (Date.now() - start < 30000) {
|
||||||
|
await new Promise(r => setTimeout(r, 2000));
|
||||||
|
const conn = await kernel.auth.connections.retrieve(connectionId);
|
||||||
|
if (conn.status === 'SUCCESS') {
|
||||||
|
console.log(` ✅ ${platform} session refreshed`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (['FAILED', 'EXPIRED', 'CANCELED'].includes(conn.status)) {
|
||||||
|
console.warn(` ⚠️ ${platform} session refresh failed: ${conn.status}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn(` ⚠️ ${platform} session refresh timed out`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify login after browser connects — if not logged in, trigger refresh and retry
|
||||||
|
*/
|
||||||
|
export async function ensureLoggedIn(page, verifyFn, platform, apiKey, maxAttempts = 2) {
|
||||||
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
const loggedIn = await verifyFn(page);
|
||||||
|
if (loggedIn) return true;
|
||||||
|
|
||||||
|
if (attempt < maxAttempts) {
|
||||||
|
console.warn(` ⚠️ ${platform} not logged in (attempt ${attempt}), refreshing session...`);
|
||||||
|
await refreshSession(platform, apiKey);
|
||||||
|
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
17
test_linkedin_login.mjs
Normal file
17
test_linkedin_login.mjs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { createBrowser } from './lib/browser.mjs';
|
||||||
|
import { verifyLogin } from './lib/linkedin.mjs';
|
||||||
|
import { loadConfig } from './lib/queue.mjs';
|
||||||
|
import { dirname, resolve } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const __dir = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const settings = loadConfig(resolve(__dir, 'config/settings.json'));
|
||||||
|
|
||||||
|
console.log('Creating Kernel browser with LinkedIn profile...');
|
||||||
|
const b = await createBrowser(settings, 'linkedin');
|
||||||
|
console.log('Browser created, checking login...');
|
||||||
|
const loggedIn = await verifyLogin(b.page);
|
||||||
|
console.log('Logged in:', loggedIn);
|
||||||
|
console.log('URL:', b.page.url());
|
||||||
|
await b.browser.close();
|
||||||
|
console.log('Done.');
|
||||||
Reference in New Issue
Block a user