{"repo": "cerberogs/catai", "files": {"api/user_keys_get_safe.php": {"194a0a1d201d70244c51af356bbc5c0f047a6fbd": {"t": 1785745764.6350589, "n": 2034, "h": "5367c342d17a24bd", "c": "'invalid-user'], 401);\n\n $providers = [\n 'gemini' => 'GEMINI_API_KEY',\n 'openai' => 'OPENAI_API_KEY',\n 'xai' => 'XAI_API_KEY',\n 'claude' => 'ANTHROPIC_API_KEY',\n 'deepseek' => 'DEEPSEEK_API_KEY',\n 'tiingo' => 'TIINGO_API_KEY',\n 'finnhub' => 'FINNHUB_API_KEY',\n 'alphavantage' => 'ALPHAVANTAGE_API_KEY',\n 'polygon' => 'POLYGON_API_KEY',\n ];\n\n // Función para obtener clave con nuevo sistema de cifrado\n function get_api_key_external_crypto($userId, $provider) {\n try {\n $pdo = db();\n $stmt = $pdo->prepare('SELECT api_key_enc, last4, status FROM user_api_keys \n WHERE user_id = ? AND provider = ? AND status = \"active\"');\n $stmt->execute([$userId, $provider]);\n $row = $stmt->fetch(PDO::FETCH_ASSOC);\n \n if (!$row) {\n return null;\n }\n \n // Descifrar con el nuevo sistema\n $decryptedKey = catai_decrypt($row['api_key_enc']);\n return [\n 'key' => $decryptedKey,\n 'last4' => $row['last4'],\n 'status' => $row['status']\n ];\n } catch (Exception $e) {\n error_log(\"Error getting API key for user $userId, provider $provider: \" . $e->getMessage());\n return null;\n }\n }\n\n $keys = [];\n foreach ($providers as $prov => $env) {\n $k = get_api_key_external_crypto($userId, $prov);\n $keys[$prov] = [\n 'has' => !empty($k),\n 'last4' => $k['last4'] ?? null,\n 'status' => $k['status'] ?? null,\n ];\n }\n\n json_out(['ok'=>true, 'storage'=>'db', 'keys'=>$keys], 200);\n\n} catch (Throwable $e) {\n json_out(['error'=>'user-keys-get-failed','detail'=>$e->getMessage()], 500);\n}\n"}, "eb018491886c87ea71cdbe040bccaa60e1e5aa59": {"t": 1785756282.703903, "n": 2034, "h": "5367c342d17a24bd", "c": "'invalid-user'], 401);\n\n $providers = [\n 'gemini' => 'GEMINI_API_KEY',\n 'openai' => 'OPENAI_API_KEY',\n 'xai' => 'XAI_API_KEY',\n 'claude' => 'ANTHROPIC_API_KEY',\n 'deepseek' => 'DEEPSEEK_API_KEY',\n 'tiingo' => 'TIINGO_API_KEY',\n 'finnhub' => 'FINNHUB_API_KEY',\n 'alphavantage' => 'ALPHAVANTAGE_API_KEY',\n 'polygon' => 'POLYGON_API_KEY',\n ];\n\n // Función para obtener clave con nuevo sistema de cifrado\n function get_api_key_external_crypto($userId, $provider) {\n try {\n $pdo = db();\n $stmt = $pdo->prepare('SELECT api_key_enc, last4, status FROM user_api_keys \n WHERE user_id = ? AND provider = ? AND status = \"active\"');\n $stmt->execute([$userId, $provider]);\n $row = $stmt->fetch(PDO::FETCH_ASSOC);\n \n if (!$row) {\n return null;\n }\n \n // Descifrar con el nuevo sistema\n $decryptedKey = catai_decrypt($row['api_key_enc']);\n return [\n 'key' => $decryptedKey,\n 'last4' => $row['last4'],\n 'status' => $row['status']\n ];\n } catch (Exception $e) {\n error_log(\"Error getting API key for user $userId, provider $provider: \" . $e->getMessage());\n return null;\n }\n }\n\n $keys = [];\n foreach ($providers as $prov => $env) {\n $k = get_api_key_external_crypto($userId, $prov);\n $keys[$prov] = [\n 'has' => !empty($k),\n 'last4' => $k['last4'] ?? null,\n 'status' => $k['status'] ?? null,\n ];\n }\n\n json_out(['ok'=>true, 'storage'=>'db', 'keys'=>$keys], 200);\n\n} catch (Throwable $e) {\n json_out(['error'=>'user-keys-get-failed','detail'=>$e->getMessage()], 500);\n}\n"}, "5bcc515fc69fe35351d4b11248c99940904d58d0": {"t": 1785756283.9043264, "n": 1069, "h": "d24b73a5418245ba", "c": "'invalid-user'], 401);\n\n $providers = [\n 'gemini' => 'GEMINI_API_KEY',\n 'openai' => 'OPENAI_API_KEY',\n 'xai' => 'XAI_API_KEY',\n 'claude' => 'ANTHROPIC_API_KEY',\n 'deepseek' => 'DEEPSEEK_API_KEY',\n 'tiingo' => 'TIINGO_API_KEY',\n 'finnhub' => 'FINNHUB_API_KEY',\n 'alphavantage' => 'ALPHAVANTAGE_API_KEY',\n 'polygon' => 'POLYGON_API_KEY',\n ];\n\n $keys = [];\n foreach ($providers as $prov => $env) {\n $k = get_api_key_for($userId, $prov, $env);\n $keys[$prov] = [\n 'has' => $k !== '',\n 'last4' => $k !== '' ? substr($k, -4) : null,\n ];\n }\n\n json_out(['ok'=>true, 'storage'=>'db', 'keys'=>$keys], 200);\n\n} catch (Throwable $e) {\n json_out(['error'=>'user-keys-get-failed','detail'=>$e->getMessage()], 500);\n}\n"}}, "api/ia_diag_safe.php": {"194a0a1d201d70244c51af356bbc5c0f047a6fbd": {"t": 1785745771.8788388, "n": 841, "h": "a4c89a94b24c3e21", "c": " !!cfg('GEMINI_API_KEY') || true,\n 'openai' => !!cfg('OPENAI_API_KEY') || true,\n 'xai' => !!cfg('XAI_API_KEY') || true,\n 'claude' => !!cfg('ANTHROPIC_API_KEY') || true,\n 'deepseek' => !!cfg('DEEPSEEK_API_KEY') || true,\n ];\n return json_out([\n 'ok'=>true,\n 'upload_max_filesize'=>$uploadMax,\n 'post_max_size'=>$postMax,\n 'memory_limit'=>$memLimit,\n 'providers'=>$providers,\n ]);\n} catch (Throwable $e) {\n return json_out(['ok'=>false, 'error'=>$e->getMessage()], 500);\n}\n\n\n"}, "f23e4a86b68ae48228c61aff2beb8e39c3d873c2": {"t": 1785756281.8638966, "n": 841, "h": "a4c89a94b24c3e21", "c": " !!cfg('GEMINI_API_KEY') || true,\n 'openai' => !!cfg('OPENAI_API_KEY') || true,\n 'xai' => !!cfg('XAI_API_KEY') || true,\n 'claude' => !!cfg('ANTHROPIC_API_KEY') || true,\n 'deepseek' => !!cfg('DEEPSEEK_API_KEY') || true,\n ];\n return json_out([\n 'ok'=>true,\n 'upload_max_filesize'=>$uploadMax,\n 'post_max_size'=>$postMax,\n 'memory_limit'=>$memLimit,\n 'providers'=>$providers,\n ]);\n} catch (Throwable $e) {\n return json_out(['ok'=>false, 'error'=>$e->getMessage()], 500);\n}\n\n\n"}}, "api/config_simple_safe.php": {"194a0a1d201d70244c51af356bbc5c0f047a6fbd": {"t": 1786067467.7118654, "n": 1847, "h": "d9afd322aff9b5bc", "c": " 'https://cerberogrowthsolutions.com/catai',\n 'API_BASE_URL' => 'https://cerberogrowthsolutions.com/catai/api',\n \n // Base de datos\n 'DB_HOST' => 'localhost',\n 'DB_PORT' => 3306,\n 'DB_NAME' => 'u522228883_bolsa_app',\n 'DB_USER' => 'u522228883_bolsa_user',\n 'DB_PASS' => 'Bolsa3811',\n\n // Auth (JWT)\n 'JWT_SECRET' => '2cc5ccdfa325bf6acd1ff0cc6c',\n\n // Clave maestra para cifrado\n 'ENCRYPTION_KEY_BASE64' => 'sRDEMhrt53A8Nt4u0PbUCn6S9WPFGdAiWAOvdOdmj0A=',\n\n // API keys globales (vacías)\n 'TIINGO_API_KEY' => '',\n 'ALPHAVANTAGE_API_KEY' => '',\n 'FINNHUB_API_KEY' => '',\n 'POLYGON_API_KEY' => '',\n 'GEMINI_API_KEY' => '',\n 'OPENAI_API_KEY' => '',\n 'XAI_API_KEY' => '',\n 'ANTHROPIC_API_KEY' => '',\n 'DEEPSEEK_API_KEY' => '',\n\n // Preferencias por defecto\n 'OPTIONS_DEFAULT_PROVIDER' => 'auto',\n 'OPTIONS_DEFAULT_EXPIRY_RULE' => 'nearest_friday',\n 'OPTIONS_DEFAULT_STRIKES_COUNT' => 20,\n 'OPTIONS_DEFAULT_PRICE_SOURCE' => 'series_last',\n\n // Red\n 'NET_DEFAULT_TIMEOUT_MS' => 8000,\n 'NET_DEFAULT_RETRIES' => 2,\n\n // Zona horaria\n 'APP_TIMEZONE' => 'America/Chicago',\n\n // Rutas\n 'UNIVERSE_PATH' => __DIR__ . '/../data/universe.json',\n\n // CORS\n 'ALLOWED_ORIGIN' => 'https://cerberogrowthsolutions.com/catai',\n 'ALLOWED_ORIGINS' => [\n 'https://cerberogrowthsolutions.com/catai',\n ],\n 'CORS_ALLOW_CREDENTIALS' => true,\n\n // Preferencias de red (IA)\n 'NET' => [\n 'ia_timeout_ms' => 20000,\n 'ia_retries' => 1,\n ],\n];\n\n// Establecer variable global para cfg()\n$GLOBALS['__APP_CONFIG'] = $CONFIG;\n\nreturn $CONFIG;\n"}}, "api/config.php": {"194a0a1d201d70244c51af356bbc5c0f047a6fbd": {"t": 1786067468.2510438, "n": 4832, "h": "671e4530796f3ece", "c": " $BASE_URL, // p.ej. https://dominio.com/cataiv1\n 'API_BASE_URL' => $BASE_URL . '/api', // p.ej. https://dominio.com/cataiv1/api\n \n // ───────────── Sistema de Cifrado ─────────────\n 'KEYRING_PATH' => '/home/u522228883/.secrets/catai.keyring.json', // Archivo externo de claves\n\n\n // ───────────── Base de datos ─────────────\n 'DB_HOST' => 'localhost', // Host MySQL de Hostinger (ver hPanel)\n 'DB_PORT' => 3306,\n 'DB_NAME' => 'u522228883_bolsa_app',\n 'DB_USER' => 'u522228883_bolsa_user',\n 'DB_PASS' => 'Bolsa3811',\n\n // ───────────── Auth (JWT) ───────────────\n 'JWT_SECRET' => '2cc5ccdfa325bf6acd1ff0cc6c', // rota si lo deseas\n\n // ───── Clave maestra para cifrado de secretos de usuarios ─────\n // 32 bytes Base64. Si ya tienes una, mantenla. Para generar:\n // php -r \"echo base64_encode(random_bytes(32));\"\n 'ENCRYPTION_KEY_BASE64' => 'sRDEMhrt53A8Nt4u0PbUCn6S9WPFGdAiWAOvdOdmj0A=',\n\n // ──────────── API keys globales (FALLBACK opcional) ────────────\n // Se dejan vacías a propósito: las claves por usuario vivirán en la base de datos.\n // Si quieres un fallback global temporal, puedes ponerlo aquí.\n 'TIINGO_API_KEY' => '',\n 'ALPHAVANTAGE_API_KEY' => '',\n 'FINNHUB_API_KEY' => '',\n 'POLYGON_API_KEY' => '',\n\n // ──────────── Prompts de IA ────────────\n 'AI_PROMPT_EXTRACT_DEFAULT' => 'Eres un analista de trading experto con más de 20 años de experiencia en mercados financieros. Analiza este documento y proporciona un análisis estructurado con: resumen (2-3 líneas del contenido principal), puntos_clave (5-8 conceptos fundamentales extraídos), estrategias (3-5 estrategias de trading específicas), gestion_riesgo (2-3 puntos críticos de gestión de riesgo), recomendaciones (2-3 recomendaciones prácticas para implementar).',\n 'GEMINI_API_KEY' => '',\n 'OPENAI_API_KEY' => '', // añadido por compatibilidad IA\n 'XAI_API_KEY' => '', // añadido por compatibilidad IA (Grok)\n 'ANTHROPIC_API_KEY' => '', // Claude\n 'DEEPSEEK_API_KEY' => '', // DeepSeek\n\n // ─────────── Preferencias por defecto (si el usuario aún no guardó las suyas) ───────────\n 'OPTIONS_DEFAULT_PROVIDER' => 'auto', // auto | polygon | finnhub\n 'OPTIONS_DEFAULT_EXPIRY_RULE' => 'nearest_friday', // próximo viernes disponible\n 'OPTIONS_DEFAULT_STRIKES_COUNT' => 20, // ≈20 strikes alrededor del ATM\n 'OPTIONS_DEFAULT_PRICE_SOURCE' => 'series_last', // series_last | provider\n\n // ─────────── Red: timeouts y reintentos por defecto ───────────\n 'NET_DEFAULT_TIMEOUT_MS' => 8000, // 8s por llamada\n 'NET_DEFAULT_RETRIES' => 2, // reintentos para proveedores de datos\n\n // ─────────── Zona horaria por defecto ───────────\n // El usuario podrá sobreescribirla en config.html\n 'APP_TIMEZONE' => 'America/Chicago',\n\n // ─────────── Rutas/otros ───────────\n 'UNIVERSE_PATH' => __DIR__ . '/../data/universe.json',\n\n // CORS (configurado automáticamente para portabilidad)\n 'ALLOWED_ORIGIN' => $BASE_URL,\n // Lista explícita de orígenes permitidos para CORS (mejores prácticas)\n // Incluye el dominio detectado automáticamente + localhost para desarrollo\n 'ALLOWED_ORIGINS' => [\n $BASE_URL,\n // Para desarrollo local\n 'http://localhost',\n 'http://127.0.0.1',\n 'http://localhost:8000',\n 'http://127.0.0.1:8000',\n ],\n // Controla si se permiten credenciales en CORS (cookies/autorización). Por defecto true.\n 'CORS_ALLOW_CREDENTIALS' => true,\n\n // Preferencias de red (IA)\n 'NET' => [\n 'ia_timeout_ms' => 20000,\n 'ia_retries' => 1,\n ],\n];\n\n// Establecer variable global para cfg()\n$GLOBALS['__APP_CONFIG'] = $CONFIG;\n\nreturn $CONFIG;\n"}}}}