Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 39 additions & 39 deletions src/config/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,33 +106,51 @@ async function getOrgIdForProject(projectId: string): Promise<string> {
}

// ============================================================================
// Integration credentials — direct by category + role
// Internal: 3-step env/worker/DB resolution helper
// ============================================================================

/**
* Resolve an integration credential for a project by category and role.
* Throws if the credential is not found.
* Resolve a credential value using the standard 3-step pattern:
* 1. Check process.env (populated at worker startup from router-supplied credentials)
* 2. If in worker context (CASCADE_CREDENTIAL_KEYS set), credential is absent → return notFoundValue
* 3. Otherwise resolve from DB via the provided async lookup
*/
export async function getIntegrationCredential(
projectId: string,
category: string,
role: string,
): Promise<string> {
async function resolveFromEnvOrDb<T>(
envKey: string | undefined,
notFoundValue: T,
dbLookup: () => Promise<T>,
): Promise<T> {
// Check process.env first (populated at worker startup from router-supplied credentials)
const envKey = roleToEnvVarKey(category, role);
if (envKey && process.env[envKey]) {
return process.env[envKey];
return process.env[envKey] as T;
}

// Worker context: all credentials set by router, this one doesn't exist
if (process.env.CASCADE_CREDENTIAL_KEYS) {
throw new Error(
`Integration credential '${category}/${role}' not found for project '${projectId}'`,
);
return notFoundValue;
}

// Router/dashboard context: resolve from DB
const value = await resolveIntegrationCredential(projectId, category, role);
return dbLookup();
}

// ============================================================================
// Integration credentials — direct by category + role
// ============================================================================

/**
* Resolve an integration credential for a project by category and role.
* Throws if the credential is not found.
*/
export async function getIntegrationCredential(
projectId: string,
category: string,
role: string,
): Promise<string> {
const envKey = roleToEnvVarKey(category, role);
const value = await resolveFromEnvOrDb<string | null>(envKey, null, () =>
resolveIntegrationCredential(projectId, category, role),
);
if (value) return value;

throw new Error(
Expand All @@ -148,19 +166,10 @@ export async function getIntegrationCredentialOrNull(
category: string,
role: string,
): Promise<string | null> {
// Check process.env first (populated at worker startup from router-supplied credentials)
const envKey = roleToEnvVarKey(category, role);
if (envKey && process.env[envKey]) {
return process.env[envKey];
}

// Worker context: all credentials set by router, this one doesn't exist
if (process.env.CASCADE_CREDENTIAL_KEYS) {
return null;
}

// Router/dashboard context: resolve from DB
return resolveIntegrationCredential(projectId, category, role);
return resolveFromEnvOrDb<string | null>(envKey, null, () =>
resolveIntegrationCredential(projectId, category, role),
);
}

// ============================================================================
Expand All @@ -175,19 +184,10 @@ export async function getOrgCredential(
projectId: string,
envVarKey: string,
): Promise<string | null> {
// Check process.env first (populated at worker startup from router-supplied credentials)
if (process.env[envVarKey]) {
return process.env[envVarKey];
}

// Worker context: all credentials set by router, this one doesn't exist
if (process.env.CASCADE_CREDENTIAL_KEYS) {
return null;
}

// Router/dashboard context: resolve from DB
const orgId = await getOrgIdForProject(projectId);
return resolveOrgCredential(orgId, envVarKey);
return resolveFromEnvOrDb<string | null>(envVarKey, null, async () => {
const orgId = await getOrgIdForProject(projectId);
return resolveOrgCredential(orgId, envVarKey);
});
}

// ============================================================================
Expand Down
Loading