simoncck commited on
Commit
eb6572b
·
verified ·
1 Parent(s): 8ce53da

Create login.js

Browse files
Files changed (1) hide show
  1. login.js +83 -0
login.js ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { chromium } from 'playwright';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+
5
+ /**
6
+ * Launch Playwright, sign in to n8n if needed, refresh cookie,
7
+ * save a screenshot, return status object.
8
+ */
9
+ export async function runLogin() {
10
+ let browser;
11
+ try {
12
+ browser = await chromium.launch({ args: ['--no-sandbox'] });
13
+
14
+ /* ---------- reuse cookie ---------- */
15
+ const hasState = fs.existsSync('/opt/state.json');
16
+ const context = hasState
17
+ ? await browser.newContext({ storageState: '/opt/state.json' })
18
+ : await browser.newContext();
19
+
20
+ await context.tracing.start({ screenshots: true, snapshots: true });
21
+
22
+ const page = await context.newPage();
23
+ const baseUrl = process.env.N8N_URL || 'http://localhost:5678/';
24
+ await page.goto(baseUrl, { waitUntil: 'networkidle', timeout: 60000 });
25
+
26
+ /* ---------- BASIC AUTH (optional) ---------- */
27
+ const basicUserInput = page.locator('input[type="text"]');
28
+ if (process.env.BASIC_USER && await basicUserInput.count()) {
29
+ await basicUserInput.fill(process.env.BASIC_USER);
30
+ await page.fill('input[type="password"]', process.env.BASIC_PASS || '');
31
+ await page.press('input[type="password"]', 'Enter');
32
+ }
33
+
34
+ /* ---------- detect current page ---------- */
35
+ const signInForm = page.locator('[data-test-id="signin-form"]');
36
+ const overviewTab = page.getByRole('link', { name: /^overview$/i });
37
+
38
+ let needSignIn = false;
39
+ try {
40
+ await Promise.race([
41
+ signInForm.waitFor({ state: 'visible', timeout: 45000 }),
42
+ overviewTab.waitFor({ state: 'visible', timeout: 45000 }),
43
+ ]);
44
+ needSignIn = await signInForm.count() > 0;
45
+ } catch (_) {
46
+ needSignIn = false; // neither selector appeared
47
+ }
48
+
49
+ /* ---------- perform sign-in ---------- */
50
+ if (needSignIn) {
51
+ const email = page.locator(
52
+ 'input[name="emailOrLdapLoginId"], input[name="email"]'
53
+ ).first();
54
+ const pass = page.locator('input[name="password"]').first();
55
+
56
+ await email.fill(process.env.N8N_EMAIL || '');
57
+ await pass.fill(process.env.N8N_PASSWORD || '');
58
+ await page.getByRole('button', { name: /sign in/i }).click();
59
+ await overviewTab.waitFor({ state: 'visible', timeout: 60000 });
60
+ }
61
+
62
+ /* ---------- save cookie & screenshot ---------- */
63
+ await context.storageState({ path: '/opt/state.json' });
64
+ try {
65
+ const dir = '/opt/log';
66
+ fs.mkdirSync(dir, { recursive: true });
67
+ const ts = new Date().toISOString().replace(/[:T]/g, '-').split('.')[0];
68
+ const file = path.join(dir, `overview-${ts}.png`);
69
+ await page.screenshot({ path: file, fullPage: true });
70
+ console.log('📸 Screenshot saved ->', file);
71
+ } catch (e) {
72
+ console.warn('⚠️ Could not save screenshot:', e.message);
73
+ }
74
+
75
+ await context.tracing.stop({ path: '/opt/trace.zip' });
76
+ return { ok: true, loggedIn: needSignIn ? 'fresh' : 'cookie' };
77
+ } catch (err) {
78
+ console.error('❌ runLogin error:', err);
79
+ return { ok: false, error: err.message };
80
+ } finally {
81
+ if (browser) await browser.close();
82
+ }
83
+ }