| import path from 'path'; |
| import axios from 'axios'; |
| import { logger } from '@librechat/data-schemas'; |
| import { readFileAsString } from './files'; |
|
|
| export interface GoogleServiceKey { |
| type?: string; |
| project_id?: string; |
| private_key_id?: string; |
| private_key?: string; |
| client_email?: string; |
| client_id?: string; |
| auth_uri?: string; |
| token_uri?: string; |
| auth_provider_x509_cert_url?: string; |
| client_x509_cert_url?: string; |
| [key: string]: unknown; |
| } |
|
|
| |
| |
| |
| |
| |
| export async function loadServiceKey(keyPath: string): Promise<GoogleServiceKey | null> { |
| if (!keyPath) { |
| return null; |
| } |
|
|
| let serviceKey: unknown; |
|
|
| |
| if (keyPath.trim().match(/^[A-Za-z0-9+/]+=*$/)) { |
| try { |
| const decoded = Buffer.from(keyPath.trim(), 'base64').toString('utf-8'); |
| |
| serviceKey = JSON.parse(decoded); |
| } catch { |
| |
| |
| } |
| } |
|
|
| |
| if (!serviceKey && keyPath.trim().startsWith('{')) { |
| try { |
| serviceKey = JSON.parse(keyPath); |
| } catch (error) { |
| logger.error('Failed to parse service key from stringified JSON', error); |
| return null; |
| } |
| } |
| |
| else if (!serviceKey && /^https?:\/\//.test(keyPath)) { |
| try { |
| const response = await axios.get(keyPath); |
| serviceKey = response.data; |
| } catch (error) { |
| logger.error(`Failed to fetch the service key from URL: ${keyPath}`, error); |
| return null; |
| } |
| } else if (!serviceKey) { |
| |
| try { |
| const absolutePath = path.isAbsolute(keyPath) ? keyPath : path.resolve(keyPath); |
| const { content: fileContent } = await readFileAsString(absolutePath); |
| serviceKey = JSON.parse(fileContent); |
| } catch (error) { |
| logger.error(`Failed to load service key from file: ${keyPath}`, error); |
| return null; |
| } |
| } |
|
|
| |
| if (typeof serviceKey === 'string') { |
| try { |
| serviceKey = JSON.parse(serviceKey); |
| } catch (parseError) { |
| logger.error(`Failed to parse service key JSON from ${keyPath}`, parseError); |
| return null; |
| } |
| } |
|
|
| |
| if (!serviceKey || typeof serviceKey !== 'object') { |
| logger.error(`Invalid service key format from ${keyPath}`); |
| return null; |
| } |
|
|
| |
| const key = serviceKey as GoogleServiceKey; |
| if (key.private_key && typeof key.private_key === 'string') { |
| |
| |
| |
| key.private_key = key.private_key.replace(/\\n/g, '\n'); |
|
|
| |
| key.private_key = key.private_key.split(String.raw`\n`).join('\n'); |
|
|
| |
| if (!key.private_key.includes('\n')) { |
| |
| const privateKeyMatch = key.private_key.match( |
| /^(-----BEGIN [A-Z ]+-----)(.*)(-----END [A-Z ]+-----)$/, |
| ); |
| if (privateKeyMatch) { |
| const [, header, body, footer] = privateKeyMatch; |
| |
| key.private_key = `${header}\n${body}\n${footer}`; |
| } |
| } |
| } |
|
|
| return key; |
| } |
|
|