session.ts•4.9 kB
/**
* Session management utilities for CLI
*/
import * as os from 'os';
import * as path from 'path';
import { AuthManager } from '../../core/auth/AuthManager';
import { SessionStore } from '../../core/auth/SessionStore';
import { printError } from './formatters';
// Default session directory
const DEFAULT_SESSION_DIR = path.join(os.homedir(), '.whatap-mxql');
/**
* Get session directory path
*/
export function getSessionDir(): string {
return process.env.WHATAP_SESSION_DIR || DEFAULT_SESSION_DIR;
}
/**
* Create and initialize SessionStore
*/
export function createSessionStore(): SessionStore {
return new SessionStore(getSessionDir());
}
/**
* Create and initialize AuthManager with existing session
*/
export async function createAuthManager(): Promise<AuthManager> {
const sessionStore = createSessionStore();
const authManager = new AuthManager(sessionStore);
try {
await authManager.loadSession();
return authManager;
} catch (error) {
throw new Error('No active session found. Please login first using: whatap-mxql login');
}
}
/**
* Check if user is logged in
*/
export async function isLoggedIn(): Promise<boolean> {
try {
const sessionStore = createSessionStore();
const authManager = new AuthManager(sessionStore);
await authManager.loadSession();
return true;
} catch (error) {
return false;
}
}
/**
* Require authentication (auto-login if not logged in)
*/
export async function requireAuth(): Promise<AuthManager> {
const loggedIn = await isLoggedIn();
if (loggedIn) {
return createAuthManager();
}
// Not logged in - prompt for login
console.log('');
console.log('You are not logged in.');
console.log('');
// Import inquirer dynamically to avoid circular dependency
const inquirer = require('inquirer');
const chalk = require('chalk');
const { shouldLogin } = await inquirer.prompt([
{
type: 'confirm',
name: 'shouldLogin',
message: 'Would you like to login now?',
default: true,
},
]);
if (!shouldLogin) {
console.log('');
printError('Login required to continue. Please run: whatap-mxql login');
process.exit(1);
}
// Prompt for credentials
console.log('');
console.log(chalk.gray('Enter your WhaTap credentials:'));
console.log('');
const credentials = await inquirer.prompt([
{
type: 'input',
name: 'email',
message: 'Email:',
validate: (input: string) => {
if (!input || !input.includes('@')) {
return 'Please enter a valid email address';
}
return true;
},
},
{
type: 'password',
name: 'password',
message: 'Password:',
validate: (input: string) => {
if (!input) {
return 'Password is required';
}
return true;
},
},
{
type: 'input',
name: 'url',
message: 'Service URL:',
default: 'https://service.whatap.io',
validate: (input: string) => {
if (!input || !input.startsWith('http')) {
return 'Please enter a valid URL';
}
return true;
},
},
]);
// Perform login
console.log('');
console.log(chalk.blue('ℹ'), 'Authenticating...');
try {
const sessionStore = createSessionStore();
const authManager = new AuthManager(sessionStore);
await authManager.login({
email: credentials.email,
password: credentials.password,
serviceUrl: credentials.url,
});
console.log('');
console.log(chalk.green('✓'), 'Successfully logged in!');
console.log('');
return authManager;
} catch (error: any) {
console.log('');
printError('Login failed', error);
if (error.message.includes('401') || error.message.includes('Unauthorized')) {
console.log('');
console.log(chalk.yellow('Hint: Please check your email and password'));
}
process.exit(1);
}
}
/**
* Parse time string to timestamp
*/
export function parseTime(timeStr: string): number {
// If already a number (timestamp)
if (/^\d+$/.test(timeStr)) {
return parseInt(timeStr, 10);
}
// Try ISO string
const date = new Date(timeStr);
if (!isNaN(date.getTime())) {
return date.getTime();
}
throw new Error(`Invalid time format: ${timeStr}`);
}
/**
* Parse time range preset to start/end timestamps
*/
export function parseTimeRange(range: string): { start: number; end: number } {
const now = Date.now();
const ranges: { [key: string]: number } = {
'1h': 3600000,
'6h': 6 * 3600000,
'24h': 86400000,
'7d': 7 * 86400000,
'30d': 30 * 86400000,
'90d': 90 * 86400000,
};
const duration = ranges[range.toLowerCase()];
if (!duration) {
throw new Error(`Invalid time range: ${range}. Valid ranges: 1h, 6h, 24h, 7d, 30d, 90d`);
}
return {
start: now - duration,
end: now,
};
}