/**
* Session Manager
* Handles authentication state and session validation
*/
import { extractLinkedInCookiesFromChrome, type LinkedInCookies } from "./chrome-cookies.js";
// Session state
let cachedCookies: LinkedInCookies | null = null;
let currentSessionId: string | null = null;
let sessionCreatedAt: Date | null = null;
// Session expires after 1 hour
const SESSION_EXPIRY_MS = 60 * 60 * 1000;
/**
* Generate a unique session ID
*/
function generateSessionId(): string {
const timestamp = Date.now().toString(36);
const random = Math.random().toString(36).substring(2, 10);
return `li_${timestamp}_${random}`;
}
/**
* Check if session has expired
*/
function isSessionExpired(): boolean {
if (!sessionCreatedAt) return true;
return Date.now() - sessionCreatedAt.getTime() > SESSION_EXPIRY_MS;
}
/**
* Authenticate - extract cookies from Chrome and create session
*/
export async function authenticate(): Promise<{
success: boolean;
sessionId?: string;
expiresAt?: string;
error?: string;
}> {
try {
const cookies = await extractLinkedInCookiesFromChrome();
if (!cookies || !cookies.li_at) {
return {
success: false,
error: "No LinkedIn cookies found in Chrome. Make sure you're logged into LinkedIn in Chrome, then close Chrome and try again.",
};
}
// Create new session
cachedCookies = cookies;
sessionCreatedAt = new Date();
currentSessionId = generateSessionId();
const expiresAt = new Date(sessionCreatedAt.getTime() + SESSION_EXPIRY_MS);
return {
success: true,
sessionId: currentSessionId,
expiresAt: expiresAt.toISOString(),
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : "Failed to extract cookies from Chrome",
};
}
}
/**
* Validate a session ID - must match current session and not be expired
*/
export function validateSession(sessionId: string | undefined): {
valid: boolean;
error?: string
} {
// No session ID provided
if (!sessionId) {
return {
valid: false,
error: "Missing session_id. Call linkedin_auth first to get a session ID."
};
}
// No active session
if (!currentSessionId || !cachedCookies) {
return {
valid: false,
error: "No active session. Call linkedin_auth first."
};
}
// Session ID doesn't match
if (sessionId !== currentSessionId) {
return {
valid: false,
error: "Invalid session_id. Call linkedin_auth to get a new session ID."
};
}
// Session expired
if (isSessionExpired()) {
clearSession();
return {
valid: false,
error: "Session expired. Call linkedin_auth to start a new session."
};
}
return { valid: true };
}
/**
* Get credentials (only if session is valid)
*/
export function getCredentials(): { liAt: string; csrfToken: string } | null {
if (!cachedCookies || isSessionExpired()) {
return null;
}
return { liAt: cachedCookies.li_at, csrfToken: cachedCookies.csrfToken };
}
/**
* Get current session ID
*/
export function getSessionId(): string | null {
return currentSessionId;
}
/**
* Clear session
*/
export function clearSession(): void {
cachedCookies = null;
currentSessionId = null;
sessionCreatedAt = null;
}
/**
* Check if there's a valid session
*/
export function hasValidSession(): boolean {
return cachedCookies !== null && !isSessionExpired();
}