@cosmocoder/mcp-web-docs 1.0.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/LICENSE +22 -0
- package/README.md +368 -0
- package/build/__mocks__/embeddings.d.ts +17 -0
- package/build/__mocks__/embeddings.js +66 -0
- package/build/__mocks__/embeddings.js.map +1 -0
- package/build/config.d.ts +44 -0
- package/build/config.js +158 -0
- package/build/config.js.map +1 -0
- package/build/config.test.d.ts +1 -0
- package/build/config.test.js +165 -0
- package/build/config.test.js.map +1 -0
- package/build/crawler/auth.d.ts +128 -0
- package/build/crawler/auth.js +546 -0
- package/build/crawler/auth.js.map +1 -0
- package/build/crawler/auth.test.d.ts +1 -0
- package/build/crawler/auth.test.js +174 -0
- package/build/crawler/auth.test.js.map +1 -0
- package/build/crawler/base.d.ts +24 -0
- package/build/crawler/base.js +149 -0
- package/build/crawler/base.js.map +1 -0
- package/build/crawler/base.test.d.ts +1 -0
- package/build/crawler/base.test.js +234 -0
- package/build/crawler/base.test.js.map +1 -0
- package/build/crawler/browser-config.d.ts +2 -0
- package/build/crawler/browser-config.js +29 -0
- package/build/crawler/browser-config.js.map +1 -0
- package/build/crawler/browser-config.test.d.ts +1 -0
- package/build/crawler/browser-config.test.js +56 -0
- package/build/crawler/browser-config.test.js.map +1 -0
- package/build/crawler/cheerio.d.ts +11 -0
- package/build/crawler/cheerio.js +134 -0
- package/build/crawler/cheerio.js.map +1 -0
- package/build/crawler/chromium.d.ts +21 -0
- package/build/crawler/chromium.js +596 -0
- package/build/crawler/chromium.js.map +1 -0
- package/build/crawler/content-extractor-types.d.ts +25 -0
- package/build/crawler/content-extractor-types.js +2 -0
- package/build/crawler/content-extractor-types.js.map +1 -0
- package/build/crawler/content-extractors.d.ts +9 -0
- package/build/crawler/content-extractors.js +9 -0
- package/build/crawler/content-extractors.js.map +1 -0
- package/build/crawler/content-utils.d.ts +2 -0
- package/build/crawler/content-utils.js +22 -0
- package/build/crawler/content-utils.js.map +1 -0
- package/build/crawler/content-utils.test.d.ts +1 -0
- package/build/crawler/content-utils.test.js +99 -0
- package/build/crawler/content-utils.test.js.map +1 -0
- package/build/crawler/crawlee-crawler.d.ts +63 -0
- package/build/crawler/crawlee-crawler.js +342 -0
- package/build/crawler/crawlee-crawler.js.map +1 -0
- package/build/crawler/crawlee-crawler.test.d.ts +1 -0
- package/build/crawler/crawlee-crawler.test.js +280 -0
- package/build/crawler/crawlee-crawler.test.js.map +1 -0
- package/build/crawler/default-extractor.d.ts +4 -0
- package/build/crawler/default-extractor.js +26 -0
- package/build/crawler/default-extractor.js.map +1 -0
- package/build/crawler/default-extractor.test.d.ts +1 -0
- package/build/crawler/default-extractor.test.js +200 -0
- package/build/crawler/default-extractor.test.js.map +1 -0
- package/build/crawler/default.d.ts +11 -0
- package/build/crawler/default.js +138 -0
- package/build/crawler/default.js.map +1 -0
- package/build/crawler/docs-crawler.d.ts +26 -0
- package/build/crawler/docs-crawler.js +97 -0
- package/build/crawler/docs-crawler.js.map +1 -0
- package/build/crawler/docs-crawler.test.d.ts +1 -0
- package/build/crawler/docs-crawler.test.js +185 -0
- package/build/crawler/docs-crawler.test.js.map +1 -0
- package/build/crawler/factory.d.ts +6 -0
- package/build/crawler/factory.js +83 -0
- package/build/crawler/factory.js.map +1 -0
- package/build/crawler/github-pages-extractor.d.ts +4 -0
- package/build/crawler/github-pages-extractor.js +33 -0
- package/build/crawler/github-pages-extractor.js.map +1 -0
- package/build/crawler/github-pages-extractor.test.d.ts +1 -0
- package/build/crawler/github-pages-extractor.test.js +184 -0
- package/build/crawler/github-pages-extractor.test.js.map +1 -0
- package/build/crawler/github.d.ts +20 -0
- package/build/crawler/github.js +181 -0
- package/build/crawler/github.js.map +1 -0
- package/build/crawler/github.test.d.ts +1 -0
- package/build/crawler/github.test.js +326 -0
- package/build/crawler/github.test.js.map +1 -0
- package/build/crawler/puppeteer.d.ts +16 -0
- package/build/crawler/puppeteer.js +191 -0
- package/build/crawler/puppeteer.js.map +1 -0
- package/build/crawler/queue-manager.d.ts +43 -0
- package/build/crawler/queue-manager.js +169 -0
- package/build/crawler/queue-manager.js.map +1 -0
- package/build/crawler/queue-manager.test.d.ts +1 -0
- package/build/crawler/queue-manager.test.js +509 -0
- package/build/crawler/queue-manager.test.js.map +1 -0
- package/build/crawler/site-rules.d.ts +11 -0
- package/build/crawler/site-rules.js +104 -0
- package/build/crawler/site-rules.js.map +1 -0
- package/build/crawler/site-rules.test.d.ts +1 -0
- package/build/crawler/site-rules.test.js +139 -0
- package/build/crawler/site-rules.test.js.map +1 -0
- package/build/crawler/storybook-extractor.d.ts +34 -0
- package/build/crawler/storybook-extractor.js +767 -0
- package/build/crawler/storybook-extractor.js.map +1 -0
- package/build/crawler/storybook-extractor.test.d.ts +1 -0
- package/build/crawler/storybook-extractor.test.js +491 -0
- package/build/crawler/storybook-extractor.test.js.map +1 -0
- package/build/embeddings/fastembed.d.ts +25 -0
- package/build/embeddings/fastembed.js +188 -0
- package/build/embeddings/fastembed.js.map +1 -0
- package/build/embeddings/fastembed.test.d.ts +1 -0
- package/build/embeddings/fastembed.test.js +307 -0
- package/build/embeddings/fastembed.test.js.map +1 -0
- package/build/embeddings/openai.d.ts +8 -0
- package/build/embeddings/openai.js +56 -0
- package/build/embeddings/openai.js.map +1 -0
- package/build/embeddings/types.d.ts +4 -0
- package/build/embeddings/types.js +2 -0
- package/build/embeddings/types.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +1007 -0
- package/build/index.js.map +1 -0
- package/build/index.test.d.ts +1 -0
- package/build/index.test.js +364 -0
- package/build/index.test.js.map +1 -0
- package/build/indexing/queue-manager.d.ts +36 -0
- package/build/indexing/queue-manager.js +86 -0
- package/build/indexing/queue-manager.js.map +1 -0
- package/build/indexing/queue-manager.test.d.ts +1 -0
- package/build/indexing/queue-manager.test.js +257 -0
- package/build/indexing/queue-manager.test.js.map +1 -0
- package/build/indexing/status.d.ts +39 -0
- package/build/indexing/status.js +207 -0
- package/build/indexing/status.js.map +1 -0
- package/build/indexing/status.test.d.ts +1 -0
- package/build/indexing/status.test.js +246 -0
- package/build/indexing/status.test.js.map +1 -0
- package/build/processor/content.d.ts +16 -0
- package/build/processor/content.js +286 -0
- package/build/processor/content.js.map +1 -0
- package/build/processor/content.test.d.ts +1 -0
- package/build/processor/content.test.js +369 -0
- package/build/processor/content.test.js.map +1 -0
- package/build/processor/markdown.d.ts +11 -0
- package/build/processor/markdown.js +256 -0
- package/build/processor/markdown.js.map +1 -0
- package/build/processor/markdown.test.d.ts +1 -0
- package/build/processor/markdown.test.js +312 -0
- package/build/processor/markdown.test.js.map +1 -0
- package/build/processor/metadata-parser.d.ts +37 -0
- package/build/processor/metadata-parser.js +245 -0
- package/build/processor/metadata-parser.js.map +1 -0
- package/build/processor/metadata-parser.test.d.ts +1 -0
- package/build/processor/metadata-parser.test.js +357 -0
- package/build/processor/metadata-parser.test.js.map +1 -0
- package/build/processor/processor.d.ts +8 -0
- package/build/processor/processor.js +190 -0
- package/build/processor/processor.js.map +1 -0
- package/build/processor/processor.test.d.ts +1 -0
- package/build/processor/processor.test.js +357 -0
- package/build/processor/processor.test.js.map +1 -0
- package/build/rag/cache.d.ts +10 -0
- package/build/rag/cache.js +10 -0
- package/build/rag/cache.js.map +1 -0
- package/build/rag/code-generator.d.ts +11 -0
- package/build/rag/code-generator.js +30 -0
- package/build/rag/code-generator.js.map +1 -0
- package/build/rag/context-assembler.d.ts +23 -0
- package/build/rag/context-assembler.js +113 -0
- package/build/rag/context-assembler.js.map +1 -0
- package/build/rag/docs-search.d.ts +55 -0
- package/build/rag/docs-search.js +380 -0
- package/build/rag/docs-search.js.map +1 -0
- package/build/rag/pipeline.d.ts +26 -0
- package/build/rag/pipeline.js +91 -0
- package/build/rag/pipeline.js.map +1 -0
- package/build/rag/query-processor.d.ts +14 -0
- package/build/rag/query-processor.js +57 -0
- package/build/rag/query-processor.js.map +1 -0
- package/build/rag/reranker.d.ts +55 -0
- package/build/rag/reranker.js +210 -0
- package/build/rag/reranker.js.map +1 -0
- package/build/rag/response-generator.d.ts +20 -0
- package/build/rag/response-generator.js +101 -0
- package/build/rag/response-generator.js.map +1 -0
- package/build/rag/retriever.d.ts +19 -0
- package/build/rag/retriever.js +111 -0
- package/build/rag/retriever.js.map +1 -0
- package/build/rag/validator.d.ts +22 -0
- package/build/rag/validator.js +128 -0
- package/build/rag/validator.js.map +1 -0
- package/build/rag/version-manager.d.ts +23 -0
- package/build/rag/version-manager.js +98 -0
- package/build/rag/version-manager.js.map +1 -0
- package/build/setupTests.d.ts +4 -0
- package/build/setupTests.js +50 -0
- package/build/setupTests.js.map +1 -0
- package/build/storage/storage.d.ts +38 -0
- package/build/storage/storage.js +700 -0
- package/build/storage/storage.js.map +1 -0
- package/build/storage/storage.test.d.ts +1 -0
- package/build/storage/storage.test.js +338 -0
- package/build/storage/storage.test.js.map +1 -0
- package/build/types/rag.d.ts +27 -0
- package/build/types/rag.js +2 -0
- package/build/types/rag.js.map +1 -0
- package/build/types.d.ts +120 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/util/content-utils.d.ts +31 -0
- package/build/util/content-utils.js +120 -0
- package/build/util/content-utils.js.map +1 -0
- package/build/util/content.d.ts +1 -0
- package/build/util/content.js +16 -0
- package/build/util/content.js.map +1 -0
- package/build/util/docs.d.ts +1 -0
- package/build/util/docs.js +26 -0
- package/build/util/docs.js.map +1 -0
- package/build/util/docs.test.d.ts +1 -0
- package/build/util/docs.test.js +49 -0
- package/build/util/docs.test.js.map +1 -0
- package/build/util/favicon.d.ts +6 -0
- package/build/util/favicon.js +88 -0
- package/build/util/favicon.js.map +1 -0
- package/build/util/favicon.test.d.ts +1 -0
- package/build/util/favicon.test.js +140 -0
- package/build/util/favicon.test.js.map +1 -0
- package/build/util/logger.d.ts +17 -0
- package/build/util/logger.js +72 -0
- package/build/util/logger.js.map +1 -0
- package/build/util/logger.test.d.ts +1 -0
- package/build/util/logger.test.js +46 -0
- package/build/util/logger.test.js.map +1 -0
- package/build/util/security.d.ts +312 -0
- package/build/util/security.js +719 -0
- package/build/util/security.js.map +1 -0
- package/build/util/security.test.d.ts +1 -0
- package/build/util/security.test.js +524 -0
- package/build/util/security.test.js.map +1 -0
- package/build/util/site-detector.d.ts +22 -0
- package/build/util/site-detector.js +42 -0
- package/build/util/site-detector.js.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
import { chromium, firefox, webkit } from 'playwright';
|
|
2
|
+
import { mkdir, readFile, writeFile, access, chmod } from 'node:fs/promises';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import defaultBrowser from 'default-browser';
|
|
5
|
+
import { logger } from '../util/logger.js';
|
|
6
|
+
import { encryptData, decryptData, createSafeRegex, isSafeRegex, StorageStateSchema, StoredSessionSchema, safeJsonParse, detectLoginPage, isLoginPageUrl, SessionExpiredError, } from '../util/security.js';
|
|
7
|
+
/**
|
|
8
|
+
* Detect the user's default browser from OS settings using the default-browser package
|
|
9
|
+
* https://github.com/sindresorhus/default-browser
|
|
10
|
+
*/
|
|
11
|
+
export async function detectDefaultBrowser() {
|
|
12
|
+
logger.info(`[Auth] === Detecting default browser ===`);
|
|
13
|
+
try {
|
|
14
|
+
logger.info(`[Auth] Calling default-browser package...`);
|
|
15
|
+
const browser = await defaultBrowser();
|
|
16
|
+
logger.info(`[Auth] ✓ default-browser returned: name="${browser.name}", id="${browser.id}"`);
|
|
17
|
+
const id = browser.id.toLowerCase();
|
|
18
|
+
const name = browser.name.toLowerCase();
|
|
19
|
+
if (id.includes('firefox') || name.includes('firefox')) {
|
|
20
|
+
logger.info(`[Auth] → Mapped to: firefox`);
|
|
21
|
+
return 'firefox';
|
|
22
|
+
}
|
|
23
|
+
if (id.includes('chrome') || name.includes('chrome')) {
|
|
24
|
+
logger.info(`[Auth] → Mapped to: chrome`);
|
|
25
|
+
return 'chrome';
|
|
26
|
+
}
|
|
27
|
+
if (id.includes('edge') || name.includes('edge')) {
|
|
28
|
+
logger.info(`[Auth] → Mapped to: edge`);
|
|
29
|
+
return 'edge';
|
|
30
|
+
}
|
|
31
|
+
if (id.includes('safari') || name.includes('safari')) {
|
|
32
|
+
logger.info(`[Auth] → Mapped to: webkit (Safari)`);
|
|
33
|
+
return 'webkit';
|
|
34
|
+
}
|
|
35
|
+
if (id.includes('chromium') || name.includes('chromium')) {
|
|
36
|
+
logger.info(`[Auth] → Mapped to: chromium`);
|
|
37
|
+
return 'chromium';
|
|
38
|
+
}
|
|
39
|
+
// Unknown browser, default to chromium
|
|
40
|
+
logger.warn(`[Auth] Unknown browser "${browser.name}" (id: ${browser.id}), falling back to chromium`);
|
|
41
|
+
return 'chromium';
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const err = error;
|
|
45
|
+
logger.error(`[Auth] ✗ default-browser package threw an error:`);
|
|
46
|
+
logger.error(`[Auth] Error name: ${err?.name}`);
|
|
47
|
+
logger.error(`[Auth] Error message: ${err?.message}`);
|
|
48
|
+
logger.error(`[Auth] Error stack: ${err?.stack}`);
|
|
49
|
+
logger.info('[Auth] Falling back to chromium');
|
|
50
|
+
return 'chromium';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Manages authentication sessions for crawling protected pages.
|
|
55
|
+
* Opens a visible browser for user to login, then saves the session for reuse.
|
|
56
|
+
*/
|
|
57
|
+
export class AuthManager {
|
|
58
|
+
sessionsDir;
|
|
59
|
+
activeBrowser = null;
|
|
60
|
+
activeContext = null;
|
|
61
|
+
constructor(dataDir) {
|
|
62
|
+
this.sessionsDir = join(dataDir, 'sessions');
|
|
63
|
+
}
|
|
64
|
+
async initialize() {
|
|
65
|
+
await mkdir(this.sessionsDir, { recursive: true });
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the session file path for a domain with path traversal protection
|
|
69
|
+
*/
|
|
70
|
+
getSessionPath(domain) {
|
|
71
|
+
// Strict sanitization - only allow alphanumeric, dots, and hyphens
|
|
72
|
+
// Limit length to prevent filesystem issues
|
|
73
|
+
const safeDomain = domain
|
|
74
|
+
.toLowerCase()
|
|
75
|
+
.replace(/[^a-z0-9.-]/g, '_')
|
|
76
|
+
.slice(0, 100);
|
|
77
|
+
if (!safeDomain || safeDomain === '.' || safeDomain === '..') {
|
|
78
|
+
throw new Error('Invalid domain for session storage');
|
|
79
|
+
}
|
|
80
|
+
const filename = `${safeDomain}.json`;
|
|
81
|
+
const fullPath = resolve(this.sessionsDir, filename);
|
|
82
|
+
// Verify the resolved path stays within the sessions directory (path traversal protection)
|
|
83
|
+
const resolvedSessionsDir = resolve(this.sessionsDir);
|
|
84
|
+
if (!fullPath.startsWith(resolvedSessionsDir + '/') && fullPath !== resolvedSessionsDir) {
|
|
85
|
+
throw new Error('Invalid session path: path traversal detected');
|
|
86
|
+
}
|
|
87
|
+
return fullPath;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check if we have a saved session for a domain
|
|
91
|
+
*/
|
|
92
|
+
async hasSession(url) {
|
|
93
|
+
const domain = new URL(url).hostname;
|
|
94
|
+
const sessionPath = this.getSessionPath(domain);
|
|
95
|
+
try {
|
|
96
|
+
await access(sessionPath);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Load a saved session for a domain
|
|
105
|
+
* Sessions are encrypted at rest and validated on load
|
|
106
|
+
*/
|
|
107
|
+
async loadSession(url) {
|
|
108
|
+
const domain = new URL(url).hostname;
|
|
109
|
+
const sessionPath = this.getSessionPath(domain);
|
|
110
|
+
try {
|
|
111
|
+
const data = await readFile(sessionPath, 'utf-8');
|
|
112
|
+
// Validate the session structure
|
|
113
|
+
const session = safeJsonParse(data, StoredSessionSchema);
|
|
114
|
+
// Decrypt the storage state
|
|
115
|
+
const decryptedStorageState = decryptData(session.storageState);
|
|
116
|
+
// Validate the decrypted storage state structure
|
|
117
|
+
safeJsonParse(decryptedStorageState, StorageStateSchema);
|
|
118
|
+
logger.info(`[AuthManager] Loaded and validated saved session for ${domain}`);
|
|
119
|
+
return decryptedStorageState;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
123
|
+
logger.debug(`[AuthManager] Failed to load session for ${domain}: ${errorMsg}`);
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Save a session for a domain with encryption
|
|
129
|
+
* The storage state is encrypted before being written to disk
|
|
130
|
+
*/
|
|
131
|
+
async saveSession(url, storageState, browser) {
|
|
132
|
+
const domain = new URL(url).hostname;
|
|
133
|
+
const sessionPath = this.getSessionPath(domain);
|
|
134
|
+
// Validate the storage state structure before saving
|
|
135
|
+
safeJsonParse(storageState, StorageStateSchema);
|
|
136
|
+
// Encrypt the storage state before saving
|
|
137
|
+
const encryptedStorageState = encryptData(storageState);
|
|
138
|
+
const session = {
|
|
139
|
+
domain,
|
|
140
|
+
storageState: encryptedStorageState,
|
|
141
|
+
createdAt: new Date().toISOString(),
|
|
142
|
+
browser,
|
|
143
|
+
version: 2, // Schema version for future migrations
|
|
144
|
+
};
|
|
145
|
+
// Write with restrictive permissions (owner read/write only)
|
|
146
|
+
await writeFile(sessionPath, JSON.stringify(session, null, 2), { mode: 0o600 });
|
|
147
|
+
// Ensure permissions are set correctly (in case file already existed)
|
|
148
|
+
await chmod(sessionPath, 0o600);
|
|
149
|
+
logger.info(`[AuthManager] Saved encrypted session for ${domain}`);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Clear a saved session for a domain
|
|
153
|
+
*/
|
|
154
|
+
async clearSession(url) {
|
|
155
|
+
const domain = new URL(url).hostname;
|
|
156
|
+
const sessionPath = this.getSessionPath(domain);
|
|
157
|
+
try {
|
|
158
|
+
const { unlink } = await import('fs/promises');
|
|
159
|
+
await unlink(sessionPath);
|
|
160
|
+
logger.info(`[AuthManager] Cleared session for ${domain}`);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// Session didn't exist
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Validate that a stored session is still valid by making a test request.
|
|
168
|
+
* This detects expired sessions by checking for:
|
|
169
|
+
* 1. Redirects to login/auth pages
|
|
170
|
+
* 2. Login page content in the response
|
|
171
|
+
*
|
|
172
|
+
* @param url - The protected URL to validate against
|
|
173
|
+
* @param browserType - Browser type to use for validation
|
|
174
|
+
* @returns Validation result indicating if session is still valid
|
|
175
|
+
*/
|
|
176
|
+
async validateSession(url, browserType = 'chromium') {
|
|
177
|
+
const domain = new URL(url).hostname;
|
|
178
|
+
logger.info(`[AuthManager] Validating session for ${domain}...`);
|
|
179
|
+
const storageStateJson = await this.loadSession(url);
|
|
180
|
+
if (!storageStateJson) {
|
|
181
|
+
logger.info(`[AuthManager] No stored session found for ${domain}`);
|
|
182
|
+
return { isValid: false, reason: 'No stored session found' };
|
|
183
|
+
}
|
|
184
|
+
let browser = null;
|
|
185
|
+
let context = null;
|
|
186
|
+
try {
|
|
187
|
+
const launcher = this.getBrowserLauncher(browserType);
|
|
188
|
+
const launchOptions = this.getLaunchOptions(browserType);
|
|
189
|
+
// Launch headless browser for validation
|
|
190
|
+
browser = await launcher.launch({
|
|
191
|
+
headless: true,
|
|
192
|
+
...launchOptions,
|
|
193
|
+
});
|
|
194
|
+
const storageState = JSON.parse(storageStateJson);
|
|
195
|
+
context = await browser.newContext({ storageState });
|
|
196
|
+
const page = await context.newPage();
|
|
197
|
+
// Navigate to the protected URL and check the result
|
|
198
|
+
logger.debug(`[AuthManager] Navigating to ${url} to validate session...`);
|
|
199
|
+
const response = await page.goto(url, {
|
|
200
|
+
waitUntil: 'domcontentloaded',
|
|
201
|
+
timeout: 30000,
|
|
202
|
+
});
|
|
203
|
+
const finalUrl = page.url();
|
|
204
|
+
logger.debug(`[AuthManager] Final URL after navigation: ${finalUrl}`);
|
|
205
|
+
// Check 1: Were we redirected to a login page?
|
|
206
|
+
if (isLoginPageUrl(finalUrl) && finalUrl !== url) {
|
|
207
|
+
logger.warn(`[AuthManager] Session appears expired - redirected to login page: ${finalUrl}`);
|
|
208
|
+
return {
|
|
209
|
+
isValid: false,
|
|
210
|
+
reason: 'Redirected to login page - session has expired',
|
|
211
|
+
finalUrl,
|
|
212
|
+
loginDetection: { isLoginPage: true, confidence: 1.0, reasons: ['Redirected to login URL'] },
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// Check 2: Did we get an auth-related HTTP status?
|
|
216
|
+
const status = response?.status();
|
|
217
|
+
if (status === 401 || status === 403) {
|
|
218
|
+
logger.warn(`[AuthManager] Session appears expired - received HTTP ${status}`);
|
|
219
|
+
return {
|
|
220
|
+
isValid: false,
|
|
221
|
+
reason: `Authentication failed with HTTP ${status}`,
|
|
222
|
+
finalUrl,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
// Check 3: Does the page content look like a login page?
|
|
226
|
+
// Wait for content to load
|
|
227
|
+
await page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => { });
|
|
228
|
+
const pageContent = await page.content();
|
|
229
|
+
const bodyText = await page.evaluate(() => document.body?.textContent || '');
|
|
230
|
+
const loginDetection = detectLoginPage(bodyText + pageContent, finalUrl);
|
|
231
|
+
if (loginDetection.isLoginPage && loginDetection.confidence >= 0.5) {
|
|
232
|
+
logger.warn(`[AuthManager] Session appears expired - login page detected (confidence: ${loginDetection.confidence.toFixed(2)})`);
|
|
233
|
+
logger.debug(`[AuthManager] Login detection reasons: ${loginDetection.reasons.join(', ')}`);
|
|
234
|
+
return {
|
|
235
|
+
isValid: false,
|
|
236
|
+
reason: `Login page detected (confidence: ${Math.round(loginDetection.confidence * 100)}%)`,
|
|
237
|
+
finalUrl,
|
|
238
|
+
loginDetection,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
// Session appears valid
|
|
242
|
+
logger.info(`[AuthManager] ✓ Session for ${domain} is valid`);
|
|
243
|
+
return { isValid: true, finalUrl };
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
247
|
+
logger.error(`[AuthManager] Error validating session: ${errorMsg}`);
|
|
248
|
+
// On error, we can't confirm validity - treat as potentially invalid
|
|
249
|
+
return {
|
|
250
|
+
isValid: false,
|
|
251
|
+
reason: `Validation failed: ${errorMsg}`,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
if (context)
|
|
256
|
+
await context.close().catch(() => { });
|
|
257
|
+
if (browser)
|
|
258
|
+
await browser.close().catch(() => { });
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Validate session and throw SessionExpiredError if expired.
|
|
263
|
+
* This is a convenience method for use in crawling workflows.
|
|
264
|
+
*
|
|
265
|
+
* @param url - The protected URL to validate against
|
|
266
|
+
* @param browserType - Browser type to use for validation
|
|
267
|
+
* @throws SessionExpiredError if the session has expired
|
|
268
|
+
*/
|
|
269
|
+
async validateSessionOrThrow(url, browserType = 'chromium') {
|
|
270
|
+
const result = await this.validateSession(url, browserType);
|
|
271
|
+
if (!result.isValid) {
|
|
272
|
+
// Clear the expired session
|
|
273
|
+
await this.clearSession(url);
|
|
274
|
+
logger.info(`[AuthManager] Cleared expired session for ${new URL(url).hostname}`);
|
|
275
|
+
throw new SessionExpiredError(`Authentication session has expired: ${result.reason}`, url, result.finalUrl || url, result.loginDetection || { isLoginPage: true, confidence: 0.5, reasons: [result.reason || 'Unknown'] });
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Get the Playwright browser launcher for a browser type
|
|
280
|
+
*/
|
|
281
|
+
getBrowserLauncher(browserType) {
|
|
282
|
+
switch (browserType) {
|
|
283
|
+
case 'firefox':
|
|
284
|
+
return firefox;
|
|
285
|
+
case 'webkit':
|
|
286
|
+
return webkit;
|
|
287
|
+
case 'chromium':
|
|
288
|
+
case 'chrome':
|
|
289
|
+
case 'edge':
|
|
290
|
+
default:
|
|
291
|
+
return chromium;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Get launch options for a browser type
|
|
296
|
+
*
|
|
297
|
+
* Note: Firefox cannot use the installed browser - Playwright requires its bundled
|
|
298
|
+
* Firefox (Nightly) which includes the Juggler automation protocol.
|
|
299
|
+
* Chrome and Edge can use the installed browser via the 'channel' option.
|
|
300
|
+
*/
|
|
301
|
+
getLaunchOptions(browserType) {
|
|
302
|
+
switch (browserType) {
|
|
303
|
+
case 'chrome':
|
|
304
|
+
return { channel: 'chrome' };
|
|
305
|
+
case 'edge':
|
|
306
|
+
return { channel: 'msedge' };
|
|
307
|
+
case 'firefox':
|
|
308
|
+
// Note: Must use Playwright's bundled Firefox - regular Firefox doesn't have Juggler protocol
|
|
309
|
+
logger.info(`[AuthManager] Note: Using Playwright's bundled Firefox (regular Firefox not supported)`);
|
|
310
|
+
return {};
|
|
311
|
+
case 'webkit':
|
|
312
|
+
case 'chromium':
|
|
313
|
+
default:
|
|
314
|
+
return {};
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Open a visible browser for user to login interactively.
|
|
319
|
+
* Returns the storage state (cookies/localStorage) after successful login.
|
|
320
|
+
*
|
|
321
|
+
* Opens a fresh browser instance for the user to login manually.
|
|
322
|
+
* Note: We don't use the user's existing browser profile because:
|
|
323
|
+
* 1. Firefox locks profiles when already open
|
|
324
|
+
* 2. Playwright uses its own bundled browsers, not system browsers
|
|
325
|
+
*/
|
|
326
|
+
async performInteractiveLogin(url, options = {}) {
|
|
327
|
+
const { browser: initialBrowserType, loginSuccessPattern, loginSuccessSelector, loginUrl, loginTimeoutSecs = 300, // 5 minutes default
|
|
328
|
+
} = options;
|
|
329
|
+
let browserType = initialBrowserType;
|
|
330
|
+
logger.info(`[AuthManager] === Starting Interactive Login ===`);
|
|
331
|
+
logger.info(`[AuthManager] Target URL: ${url}`);
|
|
332
|
+
logger.info(`[AuthManager] Options: browser=${browserType || 'auto-detect'}, loginUrl=${loginUrl || 'same as target'}, timeout=${loginTimeoutSecs}s`);
|
|
333
|
+
// Auto-detect default browser type if not specified (for UI preference)
|
|
334
|
+
if (!browserType) {
|
|
335
|
+
logger.info(`[AuthManager] No browser specified, auto-detecting...`);
|
|
336
|
+
browserType = await detectDefaultBrowser();
|
|
337
|
+
}
|
|
338
|
+
logger.info(`[AuthManager] Using browser type: ${browserType}`);
|
|
339
|
+
const domain = new URL(url).hostname;
|
|
340
|
+
const targetUrl = loginUrl || url;
|
|
341
|
+
logger.info(`[AuthManager] Will open ${browserType} browser for authentication to ${domain}`);
|
|
342
|
+
logger.info(`[AuthManager] Please login in the browser window. You have ${loginTimeoutSecs} seconds.`);
|
|
343
|
+
logger.info(`[AuthManager] NOTE: This is a fresh browser - you will need to login manually.`);
|
|
344
|
+
// Always use fresh browser to avoid profile conflicts
|
|
345
|
+
return this.loginWithFreshBrowser(url, targetUrl, browserType, {
|
|
346
|
+
loginSuccessPattern,
|
|
347
|
+
loginSuccessSelector,
|
|
348
|
+
loginTimeoutSecs,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Login using a fresh browser instance (for manual login)
|
|
353
|
+
*/
|
|
354
|
+
async loginWithFreshBrowser(url, targetUrl, browserType, options) {
|
|
355
|
+
const { loginSuccessPattern, loginSuccessSelector, loginTimeoutSecs } = options;
|
|
356
|
+
const domain = new URL(url).hostname;
|
|
357
|
+
const launcher = this.getBrowserLauncher(browserType);
|
|
358
|
+
const launchOptions = this.getLaunchOptions(browserType);
|
|
359
|
+
logger.info(`[AuthManager] Launching fresh ${browserType} browser...`);
|
|
360
|
+
logger.debug(`[AuthManager] Launch options:`, launchOptions);
|
|
361
|
+
try {
|
|
362
|
+
// Launch visible browser
|
|
363
|
+
this.activeBrowser = await launcher.launch({
|
|
364
|
+
headless: false, // VISIBLE browser for user interaction
|
|
365
|
+
...launchOptions,
|
|
366
|
+
});
|
|
367
|
+
logger.info(`[AuthManager] ✓ Browser launched successfully`);
|
|
368
|
+
this.activeContext = await this.activeBrowser.newContext({
|
|
369
|
+
viewport: { width: 1280, height: 800 },
|
|
370
|
+
});
|
|
371
|
+
logger.debug(`[AuthManager] ✓ Browser context created`);
|
|
372
|
+
const page = await this.activeContext.newPage();
|
|
373
|
+
logger.debug(`[AuthManager] ✓ New page created`);
|
|
374
|
+
// Navigate to login page
|
|
375
|
+
logger.info(`[AuthManager] Navigating to: ${targetUrl}`);
|
|
376
|
+
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
|
|
377
|
+
logger.info(`[AuthManager] ✓ Page loaded. Waiting for user to login...`);
|
|
378
|
+
logger.info(`[AuthManager] ⏳ You have ${loginTimeoutSecs} seconds to complete login.`);
|
|
379
|
+
// Wait for successful login
|
|
380
|
+
const loginSuccess = await this.waitForLogin(page, {
|
|
381
|
+
successPattern: loginSuccessPattern,
|
|
382
|
+
successSelector: loginSuccessSelector,
|
|
383
|
+
timeoutSecs: loginTimeoutSecs,
|
|
384
|
+
});
|
|
385
|
+
if (!loginSuccess) {
|
|
386
|
+
logger.error(`[AuthManager] ✗ Login timed out after ${loginTimeoutSecs} seconds`);
|
|
387
|
+
throw new Error('Login timed out or was cancelled');
|
|
388
|
+
}
|
|
389
|
+
logger.info(`[AuthManager] ✓ Login detected!`);
|
|
390
|
+
// Extract and save the storage state
|
|
391
|
+
const storageState = await this.activeContext.storageState();
|
|
392
|
+
const storageStateJson = JSON.stringify(storageState);
|
|
393
|
+
logger.debug(`[AuthManager] Storage state captured (${storageStateJson.length} bytes)`);
|
|
394
|
+
await this.saveSession(url, storageStateJson, browserType);
|
|
395
|
+
logger.info(`[AuthManager] ✓ Session saved for ${domain}`);
|
|
396
|
+
return storageStateJson;
|
|
397
|
+
}
|
|
398
|
+
finally {
|
|
399
|
+
await this.cleanup();
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Wait for the user to complete login.
|
|
404
|
+
*
|
|
405
|
+
* Detection methods (in order of priority):
|
|
406
|
+
* 1. If successPattern is provided: wait for URL to match the regex
|
|
407
|
+
* 2. If successSelector is provided: wait for the CSS selector to appear
|
|
408
|
+
* 3. Default: poll for common login success indicators (logout button, user menu, URL change)
|
|
409
|
+
*/
|
|
410
|
+
async waitForLogin(page, options) {
|
|
411
|
+
const { successPattern, successSelector, timeoutSecs } = options;
|
|
412
|
+
const startTime = Date.now();
|
|
413
|
+
const timeoutMs = timeoutSecs * 1000;
|
|
414
|
+
logger.debug(`[AuthManager] Login detection method: ${successPattern
|
|
415
|
+
? `URL pattern: ${successPattern}`
|
|
416
|
+
: successSelector
|
|
417
|
+
? `CSS selector: ${successSelector}`
|
|
418
|
+
: 'auto-detect (looking for logout button, user menu, or URL change)'}`);
|
|
419
|
+
// If we have specific success criteria, wait for them
|
|
420
|
+
if (successPattern) {
|
|
421
|
+
// Validate the regex pattern to prevent ReDoS attacks
|
|
422
|
+
if (!isSafeRegex(successPattern)) {
|
|
423
|
+
logger.error(`[AuthManager] Unsafe regex pattern provided: ${successPattern}`);
|
|
424
|
+
throw new Error('Unsafe regex pattern: may cause catastrophic backtracking (ReDoS)');
|
|
425
|
+
}
|
|
426
|
+
const pattern = createSafeRegex(successPattern);
|
|
427
|
+
logger.info(`[AuthManager] Waiting for URL to match pattern: ${successPattern}`);
|
|
428
|
+
try {
|
|
429
|
+
await page.waitForURL(pattern, { timeout: timeoutMs });
|
|
430
|
+
logger.info(`[AuthManager] ✓ URL matched success pattern`);
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
catch {
|
|
434
|
+
logger.debug(`[AuthManager] ✗ URL did not match pattern within timeout`);
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (successSelector) {
|
|
439
|
+
logger.info(`[AuthManager] Waiting for element: ${successSelector}`);
|
|
440
|
+
try {
|
|
441
|
+
await page.waitForSelector(successSelector, { timeout: timeoutMs });
|
|
442
|
+
logger.info(`[AuthManager] ✓ Success selector found`);
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
logger.debug(`[AuthManager] ✗ Selector not found within timeout`);
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// Default: wait for navigation away from login page or for page to show logged-in state
|
|
451
|
+
// Poll for changes that indicate successful login
|
|
452
|
+
logger.info(`[AuthManager] Using auto-detection for login success...`);
|
|
453
|
+
logger.info(`[AuthManager] The browser will stay open until you login or ${timeoutSecs} seconds pass.`);
|
|
454
|
+
let lastLogTime = 0;
|
|
455
|
+
// Track the initial URL to detect navigation
|
|
456
|
+
const initialUrl = page.url();
|
|
457
|
+
let hasNavigatedAway = false;
|
|
458
|
+
let wasOnLoginPage = false;
|
|
459
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
460
|
+
try {
|
|
461
|
+
const currentUrl = page.url();
|
|
462
|
+
const elapsed = Math.round((Date.now() - startTime) / 1000);
|
|
463
|
+
// Log status every 10 seconds
|
|
464
|
+
if (elapsed - lastLogTime >= 10) {
|
|
465
|
+
logger.info(`[AuthManager] Still waiting for login... (${elapsed}s elapsed, current URL: ${currentUrl})`);
|
|
466
|
+
lastLogTime = elapsed;
|
|
467
|
+
}
|
|
468
|
+
// Check if we're on a login-like page
|
|
469
|
+
const isLoginPage = /login|signin|sign-in|auth|sso|oauth|session/i.test(currentUrl);
|
|
470
|
+
// Track if we've been to a login page (to know when we've successfully logged in)
|
|
471
|
+
if (isLoginPage) {
|
|
472
|
+
wasOnLoginPage = true;
|
|
473
|
+
logger.debug(`[AuthManager] Detected login page: ${currentUrl}`);
|
|
474
|
+
}
|
|
475
|
+
// Track navigation away from initial URL
|
|
476
|
+
if (currentUrl !== initialUrl && !hasNavigatedAway) {
|
|
477
|
+
hasNavigatedAway = true;
|
|
478
|
+
logger.debug(`[AuthManager] Navigation detected: ${initialUrl} → ${currentUrl}`);
|
|
479
|
+
}
|
|
480
|
+
// Check for common logged-in indicators
|
|
481
|
+
const hasLogoutButton = (await page.locator('text=/log\\s*out|sign\\s*out/i').count()) > 0;
|
|
482
|
+
const hasUserMenu = (await page.locator('[class*="user"], [class*="avatar"], [class*="profile"]').count()) > 0;
|
|
483
|
+
// Only consider login successful if:
|
|
484
|
+
// 1. We're not on a login page, AND
|
|
485
|
+
// 2. We have logged-in indicators OR we were on a login page and navigated away
|
|
486
|
+
if (!isLoginPage && (hasLogoutButton || hasUserMenu)) {
|
|
487
|
+
logger.info(`[AuthManager] ✓ Login indicators found (logout button or user menu)`);
|
|
488
|
+
await page.waitForTimeout(1000);
|
|
489
|
+
return true;
|
|
490
|
+
}
|
|
491
|
+
// For GitHub Pages: only consider successful if we were on login page and came back
|
|
492
|
+
if (currentUrl.includes('github.io') && wasOnLoginPage && !isLoginPage) {
|
|
493
|
+
// We were redirected to login and now we're back on the github.io page
|
|
494
|
+
const bodyText = (await page.locator('body').textContent()) || '';
|
|
495
|
+
// Make sure it's not an error page
|
|
496
|
+
if (bodyText.length > 100 && !bodyText.includes('404') && !bodyText.includes('not found')) {
|
|
497
|
+
logger.info(`[AuthManager] ✓ Returned to GitHub Pages after login`);
|
|
498
|
+
await page.waitForTimeout(1000);
|
|
499
|
+
return true;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// Wait a bit before checking again
|
|
503
|
+
await page.waitForTimeout(1000);
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
// Page might have navigated, which is fine
|
|
507
|
+
logger.debug(`[AuthManager] Error during login check (may be normal during navigation):`, error);
|
|
508
|
+
await page.waitForTimeout(1000);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
logger.warn(`[AuthManager] Login detection timed out after ${timeoutSecs} seconds`);
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Create a browser context with saved authentication
|
|
516
|
+
*/
|
|
517
|
+
async createAuthenticatedContext(url, browserType = 'chromium') {
|
|
518
|
+
const storageStateJson = await this.loadSession(url);
|
|
519
|
+
if (!storageStateJson) {
|
|
520
|
+
return null;
|
|
521
|
+
}
|
|
522
|
+
const launcher = this.getBrowserLauncher(browserType);
|
|
523
|
+
const launchOptions = this.getLaunchOptions(browserType);
|
|
524
|
+
const browser = await launcher.launch({
|
|
525
|
+
headless: true,
|
|
526
|
+
...launchOptions,
|
|
527
|
+
});
|
|
528
|
+
const storageState = JSON.parse(storageStateJson);
|
|
529
|
+
const context = await browser.newContext({ storageState });
|
|
530
|
+
return { browser, context };
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Clean up any active browser instances
|
|
534
|
+
*/
|
|
535
|
+
async cleanup() {
|
|
536
|
+
if (this.activeContext) {
|
|
537
|
+
await this.activeContext.close().catch(() => { });
|
|
538
|
+
this.activeContext = null;
|
|
539
|
+
}
|
|
540
|
+
if (this.activeBrowser) {
|
|
541
|
+
await this.activeBrowser.close().catch(() => { });
|
|
542
|
+
this.activeBrowser = null;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/crawler/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|