web_surf_API / login1.js
simoncck's picture
Rename login.js to login1.js
2ca135e verified
import { chromium } from 'playwright';
import fs from 'fs';
import path from 'path';
const DIR = process.env.STATE_DIR || '/data';
const COOKIE_FILE = path.join(DIR, 'state.json');
const LOG_DIR = path.join(DIR, 'log');
/**
* Launch Playwright, sign in to n8n if needed, refresh cookie,
* save a screenshot, return status object.
*/
export async function runLogin() {
let browser;
try {
/* ---------- ensure writable paths exist ---------- */
fs.mkdirSync(LOG_DIR, { recursive: true }); // also creates DIR
browser = await chromium.launch({ args: ['--no-sandbox'] });
/* ---------- reuse cookie ---------- */
const hasCookie = fs.existsSync(COOKIE_FILE);
const context = await browser.newContext({
storageState: hasCookie ? COOKIE_FILE : undefined,
ignoreHTTPSErrors: true, // in case your n8n URL uses self-signed cert
});
const page = await context.newPage();
const baseUrl = process.env.N8N_URL || 'http://localhost:5678/';
await page.goto(baseUrl, { waitUntil: 'networkidle', timeout: 60000 });
/* ---------- BASIC AUTH (optional) ---------- */
const basicUserInput = page.locator('input[type="text"]');
if (process.env.BASIC_USER && await basicUserInput.count()) {
await basicUserInput.fill(process.env.BASIC_USER);
await page.fill('input[type="password"]', process.env.BASIC_PASS || '');
await page.press('input[type="password"]', 'Enter');
}
/* ---------- detect current page ---------- */
const signInForm = page.locator('[data-test-id="signin-form"]');
const overviewTab = page.getByRole('link', { name: /^overview$/i });
let needSignIn = false;
try {
await Promise.race([
signInForm.waitFor({ state: 'visible', timeout: 45000 }),
overviewTab.waitFor({ state: 'visible', timeout: 45000 }),
]);
needSignIn = await signInForm.count() > 0;
} catch (_) {
needSignIn = false; // neither selector appeared
}
/* ---------- perform sign-in ---------- */
if (needSignIn) {
const email = page.locator(
'input[name="emailOrLdapLoginId"], input[name="email"]'
).first();
const pass = page.locator('input[name="password"]').first();
await email.fill(process.env.N8N_EMAIL || '');
await pass.fill(process.env.N8N_PASSWORD || '');
await page.getByRole('button', { name: /sign in/i }).click();
await overviewTab.waitFor({ state: 'visible', timeout: 60000 });
}
/* save cookie */
await context.storageState({ path: COOKIE_FILE });
const ts = new Date().toISOString().replace(/[:T]/g, '-').split('.')[0];
const shot = path.join(LOG_DIR, `overview-${ts}.png`);
await page.screenshot({ path: shot, fullPage: true });
await context.tracing.stop({ path: path.join(DIR, 'trace.zip') });
return { ok: true, screenshot: shot, loggedIn: needSignIn ? 'fresh' : 'cookie' };
} catch (err) {
console.error('❌ runLogin error:', err);
return { ok: false, error: err.message };
} finally {
if (browser) await browser.close();
}
}