import {SecretManagerServiceClient} from '@google-cloud/secret-manager' import {zip} from 'lodash' import {refreshConfig} from "common/envs/prod"; import {IS_LOCAL} from "common/hosting/constants"; // List of secrets that are available to backend (api, functions, scripts, etc.) // Edit them at: // https://console.cloud.google.com/security/secret-manager?project=compass-130ba export const secrets = ( [ // 'STRIPE_APIKEY', // 'STRIPE_WEBHOOKSECRET', 'SUPABASE_KEY', 'SUPABASE_JWT_SECRET', 'SUPABASE_DB_PASSWORD', 'TEST_CREATE_USER_KEY', 'GEODB_API_KEY', 'RESEND_KEY', 'COMPASS_API_KEY', 'NEXT_PUBLIC_FIREBASE_API_KEY', 'DISCORD_WEBHOOK_MEMBERS', 'DISCORD_WEBHOOK_GENERAL', 'DISCORD_WEBHOOK_HEALTH', 'DISCORD_WEBHOOK_REPORTS', 'DISCORD_WEBHOOK_CONTACT', 'VAPID_PUBLIC_KEY', 'VAPID_PRIVATE_KEY', 'DB_ENC_MASTER_KEY_BASE64', 'GOOGLE_CLIENT_SECRET', // Some typescript voodoo to keep the string literal types while being not readonly. ] as const ).concat() type SecretId = (typeof secrets)[number] // Fetches all secrets from google cloud. // For deployed google cloud service, no credential is needed. // For local and Vercel deployments: requires credentials json object. export const getSecrets = async (credentials?: any, ...ids: SecretId[]) => { if (!ids.length && IS_LOCAL) return {} // console.debug('Fetching secrets...') let client: SecretManagerServiceClient if (credentials) { const projectId = credentials['project_id'] client = new SecretManagerServiceClient({ credentials, projectId, }) } else { client = new SecretManagerServiceClient() } const projectId = await client.getProjectId() const secretIds = ids.length > 0 ? ids : secrets console.debug('secretIds', secretIds) const fullSecretNames = secretIds.map( (secret: string) => `${client.projectPath(projectId)}/secrets/${secret}/versions/latest` ) const secretResponses = await Promise.all( fullSecretNames.map((name) => client.accessSecretVersion({ name, }) ) ) const secretValues = secretResponses.map(([response]) => response.payload!.data!.toString() ) const pairs = zip(secretIds, secretValues) as [string, string][] return Object.fromEntries(pairs) } // Fetches all secrets and loads them into process.env. // Useful for running random backend code. export const loadSecretsToEnv = async (credentials?: any) => { const allSecrets = await getSecrets(credentials) for (const [key, value] of Object.entries(allSecrets)) { if (key && value) { process.env[key] = value // console.debug(key, value) } } refreshConfig() }