refactor(settings): adopt environment-only runtime secret flow
This commit is contained in:
@@ -7,6 +7,23 @@ type RuntimeAwareSystemSettings = {
|
||||
anonymizationSeed?: string | null;
|
||||
};
|
||||
|
||||
export const RUNTIME_SECRET_FIELDS = [
|
||||
"azureOpenAiApiKey",
|
||||
"azureDalleApiKey",
|
||||
"geminiApiKey",
|
||||
"smtpPassword",
|
||||
"anonymizationSeed",
|
||||
] as const;
|
||||
|
||||
export type RuntimeSecretField = (typeof RUNTIME_SECRET_FIELDS)[number];
|
||||
|
||||
export type RuntimeSecretStatus = {
|
||||
configured: boolean;
|
||||
activeSource: "environment" | "database" | "none";
|
||||
hasStoredValue: boolean;
|
||||
envVarNames: string[];
|
||||
};
|
||||
|
||||
function readEnvOverride(...names: string[]): string | null {
|
||||
for (const name of names) {
|
||||
const value = process.env[name]?.trim();
|
||||
@@ -26,16 +43,92 @@ function resolvePrimaryAiApiKey(provider: string | null | undefined): string | n
|
||||
return readEnvOverride("OPENAI_API_KEY", "AZURE_OPENAI_API_KEY");
|
||||
}
|
||||
|
||||
function getPrimaryAiEnvVarNames(provider: string | null | undefined): string[] {
|
||||
if (provider === "azure") {
|
||||
return ["AZURE_OPENAI_API_KEY", "OPENAI_API_KEY"];
|
||||
}
|
||||
|
||||
return ["OPENAI_API_KEY", "AZURE_OPENAI_API_KEY"];
|
||||
}
|
||||
|
||||
function resolveSecretEnvOverride(
|
||||
field: RuntimeSecretField,
|
||||
provider: string | null | undefined,
|
||||
): string | null {
|
||||
if (field === "azureOpenAiApiKey") {
|
||||
return resolvePrimaryAiApiKey(provider);
|
||||
}
|
||||
if (field === "azureDalleApiKey") {
|
||||
return readEnvOverride("AZURE_DALLE_API_KEY");
|
||||
}
|
||||
if (field === "geminiApiKey") {
|
||||
return readEnvOverride("GEMINI_API_KEY");
|
||||
}
|
||||
if (field === "smtpPassword") {
|
||||
return readEnvOverride("SMTP_PASSWORD");
|
||||
}
|
||||
|
||||
return readEnvOverride("ANONYMIZATION_SEED");
|
||||
}
|
||||
|
||||
function getSecretEnvVarNames(
|
||||
field: RuntimeSecretField,
|
||||
provider: string | null | undefined,
|
||||
): string[] {
|
||||
if (field === "azureOpenAiApiKey") {
|
||||
return getPrimaryAiEnvVarNames(provider);
|
||||
}
|
||||
if (field === "azureDalleApiKey") {
|
||||
return ["AZURE_DALLE_API_KEY"];
|
||||
}
|
||||
if (field === "geminiApiKey") {
|
||||
return ["GEMINI_API_KEY"];
|
||||
}
|
||||
if (field === "smtpPassword") {
|
||||
return ["SMTP_PASSWORD"];
|
||||
}
|
||||
|
||||
return ["ANONYMIZATION_SEED"];
|
||||
}
|
||||
|
||||
export function getRuntimeSecretStatuses(
|
||||
settings: RuntimeAwareSystemSettings | null | undefined,
|
||||
): Record<RuntimeSecretField, RuntimeSecretStatus> {
|
||||
const provider = settings?.aiProvider;
|
||||
|
||||
return Object.fromEntries(
|
||||
RUNTIME_SECRET_FIELDS.map((field) => {
|
||||
const envValue = resolveSecretEnvOverride(field, provider);
|
||||
const storedValue = settings?.[field]?.trim() || null;
|
||||
const activeSource = envValue
|
||||
? "environment"
|
||||
: storedValue
|
||||
? "database"
|
||||
: "none";
|
||||
|
||||
return [
|
||||
field,
|
||||
{
|
||||
configured: !!(envValue || storedValue),
|
||||
activeSource,
|
||||
hasStoredValue: !!storedValue,
|
||||
envVarNames: getSecretEnvVarNames(field, provider),
|
||||
} satisfies RuntimeSecretStatus,
|
||||
];
|
||||
}),
|
||||
) as Record<RuntimeSecretField, RuntimeSecretStatus>;
|
||||
}
|
||||
|
||||
export function resolveSystemSettingsRuntime<T extends RuntimeAwareSystemSettings>(
|
||||
settings: T | null | undefined,
|
||||
): T & Required<Pick<RuntimeAwareSystemSettings, "azureOpenAiApiKey" | "azureDalleApiKey" | "geminiApiKey" | "smtpPassword" | "anonymizationSeed">> {
|
||||
const resolved = { ...(settings ?? {}) } as T & Required<Pick<RuntimeAwareSystemSettings, "azureOpenAiApiKey" | "azureDalleApiKey" | "geminiApiKey" | "smtpPassword" | "anonymizationSeed">>;
|
||||
|
||||
resolved.azureOpenAiApiKey = resolvePrimaryAiApiKey(resolved.aiProvider) ?? settings?.azureOpenAiApiKey ?? null;
|
||||
resolved.azureDalleApiKey = readEnvOverride("AZURE_DALLE_API_KEY") ?? settings?.azureDalleApiKey ?? null;
|
||||
resolved.geminiApiKey = readEnvOverride("GEMINI_API_KEY") ?? settings?.geminiApiKey ?? null;
|
||||
resolved.smtpPassword = readEnvOverride("SMTP_PASSWORD") ?? settings?.smtpPassword ?? null;
|
||||
resolved.anonymizationSeed = readEnvOverride("ANONYMIZATION_SEED") ?? settings?.anonymizationSeed ?? null;
|
||||
resolved.azureOpenAiApiKey = resolveSecretEnvOverride("azureOpenAiApiKey", resolved.aiProvider) ?? settings?.azureOpenAiApiKey ?? null;
|
||||
resolved.azureDalleApiKey = resolveSecretEnvOverride("azureDalleApiKey", resolved.aiProvider) ?? settings?.azureDalleApiKey ?? null;
|
||||
resolved.geminiApiKey = resolveSecretEnvOverride("geminiApiKey", resolved.aiProvider) ?? settings?.geminiApiKey ?? null;
|
||||
resolved.smtpPassword = resolveSecretEnvOverride("smtpPassword", resolved.aiProvider) ?? settings?.smtpPassword ?? null;
|
||||
resolved.anonymizationSeed = resolveSecretEnvOverride("anonymizationSeed", resolved.aiProvider) ?? settings?.anonymizationSeed ?? null;
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user