UNPKG

tinyagent

Version:

Connect your local shell to any device - access your dev environment from anywhere

218 lines • 9.27 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FirebaseAuthClient = void 0; const chalk_1 = __importDefault(require("chalk")); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const os_1 = __importDefault(require("os")); const open_1 = __importDefault(require("open")); const http_1 = __importDefault(require("http")); const url_1 = require("url"); class FirebaseAuthClient { configPath; token; constructor() { this.configPath = path_1.default.join(os_1.default.homedir(), '.tinyagent', 'auth.json'); this.loadToken(); } loadToken() { try { if (fs_1.default.existsSync(this.configPath)) { const data = fs_1.default.readFileSync(this.configPath, 'utf-8'); this.token = JSON.parse(data); } } catch (error) { // Ignore errors, token will be undefined } } saveToken(token) { try { const dir = path_1.default.dirname(this.configPath); if (!fs_1.default.existsSync(dir)) { fs_1.default.mkdirSync(dir, { recursive: true }); } fs_1.default.writeFileSync(this.configPath, JSON.stringify(token, null, 2)); this.token = token; } catch (error) { console.error(chalk_1.default.yellow('Warning: Could not save auth token')); } } isAuthenticated() { if (!this.token) return false; if (this.token.expiresAt && this.token.expiresAt < Date.now()) { return false; } return true; } getToken() { return this.isAuthenticated() ? this.token?.idToken : undefined; } getUser() { return this.isAuthenticated() ? this.token?.user : undefined; } async authenticate() { console.log(chalk_1.default.cyan('\nšŸ” Authenticating with Firebase')); try { // Create local server to receive the callback const server = http_1.default.createServer(); const port = 9005; return new Promise((resolve) => { let resolved = false; server.on('request', async (req, res) => { const url = new url_1.URL(req.url, `http://localhost:${port}`); if (url.pathname === '/auth/callback') { const idToken = url.searchParams.get('token'); const uid = url.searchParams.get('uid'); const email = url.searchParams.get('email'); const name = url.searchParams.get('name'); if (idToken && uid) { try { // Save token this.saveToken({ idToken, user: { uid, email: email || null, displayName: name || null, photoURL: null, }, expiresAt: Date.now() + (60 * 60 * 1000), // 1 hour }); // Send success response res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(` <!DOCTYPE html> <html> <head> <title>Authentication Successful</title> <style> body { font-family: -apple-system, system-ui, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #000; color: #0f0; } .success { text-align: center; } h1 { font-size: 48px; margin: 0; } p { color: #888; margin-top: 10px; } </style> </head> <body> <div class="success"> <h1>āœ“</h1> <p>Authentication successful! You can close this window.</p> </div> <script>setTimeout(() => window.close(), 2000)</script> </body> </html> `); console.log(chalk_1.default.green('\nāœ“ Authentication successful!')); if (email) { console.log(chalk_1.default.gray(`Logged in as: ${email}`)); } if (!resolved) { resolved = true; server.close(); resolve(true); } } catch (error) { console.error(chalk_1.default.red('Failed to process authentication')); res.writeHead(400); res.end('Authentication failed'); if (!resolved) { resolved = true; server.close(); resolve(false); } } } else { res.writeHead(400); res.end('Missing authentication data'); if (!resolved) { resolved = true; server.close(); resolve(false); } } } else { res.writeHead(404); res.end('Not found'); } }); server.listen(port, async () => { // For now, we'll use a simple auth page hosted on Firebase // In production, this would be your Firebase Hosting URL const authUrl = `https://tinyagent-fab3c.firebaseapp.com/auth/cli?redirect=http://localhost:${port}/auth/callback`; console.log(chalk_1.default.white('\nTo authenticate, visit:')); console.log(chalk_1.default.green.bold(authUrl)); // Open browser try { await (0, open_1.default)(authUrl); console.log(chalk_1.default.gray('\n(Browser should open automatically)')); } catch { console.log(chalk_1.default.gray('\n(Please open the URL manually in your browser)')); } console.log(chalk_1.default.gray('\nWaiting for authentication...')); }); // Timeout after 5 minutes setTimeout(() => { if (server.listening && !resolved) { console.log(chalk_1.default.red('\nāœ— Authentication timed out')); resolved = true; server.close(); resolve(false); } }, 5 * 60 * 1000); }); } catch (error) { console.error(chalk_1.default.red('\nāœ— Authentication failed:'), error); return false; } } logout() { try { if (fs_1.default.existsSync(this.configPath)) { fs_1.default.unlinkSync(this.configPath); } this.token = undefined; console.log(chalk_1.default.green('āœ“ Logged out successfully')); } catch (error) { console.error(chalk_1.default.red('āœ— Logout failed:'), error); } } whoami() { if (!this.isAuthenticated()) { console.log(chalk_1.default.yellow('Not authenticated. Run "tinyagent login" to authenticate.')); return; } const user = this.getUser(); if (user) { console.log(chalk_1.default.cyan('Current user:')); console.log(` UID: ${user.uid}`); if (user.email) { console.log(` Email: ${user.email}`); } if (user.displayName) { console.log(` Name: ${user.displayName}`); } } } } exports.FirebaseAuthClient = FirebaseAuthClient; //# sourceMappingURL=firebase-auth-simple.js.map