feat: integrated with github app connection to gateway and some adjustments

This commit is contained in:
Sheen Capadngan
2025-09-03 18:45:26 +08:00
parent d5dcaf0d59
commit 9a9cdf140a
11 changed files with 277 additions and 106 deletions
@@ -1,6 +1,7 @@
import sodium from "libsodium-wrappers";
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
import { TGatewayV2ServiceFactory } from "@app/ee/services/gateway-v2/gateway-v2-service";
import {
getGitHubAppAuthToken,
getGitHubInstanceApiUrl,
@@ -20,7 +21,8 @@ import { TGitHubPublicKey, TGitHubSecret, TGitHubSecretPayload, TGitHubSyncWithC
const getEncryptedSecrets = async (
secretSync: TGitHubSyncWithCredentials,
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">
) => {
const { destinationConfig, connection } = secretSync;
@@ -44,6 +46,7 @@ const getEncryptedSecrets = async (
return makePaginatedGitHubRequest<TGitHubSecret, { secrets: TGitHubSecret[] }>(
connection,
gatewayService,
gatewayV2Service,
path,
(data) => data.secrets
);
@@ -52,6 +55,7 @@ const getEncryptedSecrets = async (
const getPublicKey = async (
secretSync: TGitHubSyncWithCredentials,
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">,
token: string
) => {
const { destinationConfig, connection } = secretSync;
@@ -73,7 +77,7 @@ const getPublicKey = async (
}
}
const response = await requestWithGitHubGateway<TGitHubPublicKey>(connection, gatewayService, {
const response = await requestWithGitHubGateway<TGitHubPublicKey>(connection, gatewayService, gatewayV2Service, {
url: `https://${await getGitHubInstanceApiUrl(connection)}${path}`,
method: "GET",
headers: {
@@ -89,6 +93,7 @@ const getPublicKey = async (
const deleteSecret = async (
secretSync: TGitHubSyncWithCredentials,
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">,
token: string,
encryptedSecret: TGitHubSecret
) => {
@@ -111,7 +116,7 @@ const deleteSecret = async (
}
}
await requestWithGitHubGateway(connection, gatewayService, {
await requestWithGitHubGateway(connection, gatewayService, gatewayV2Service, {
url: `https://${await getGitHubInstanceApiUrl(connection)}${path}`,
method: "DELETE",
headers: {
@@ -125,6 +130,7 @@ const deleteSecret = async (
const putSecret = async (
secretSync: TGitHubSyncWithCredentials,
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">,
token: string,
payload: TGitHubSecretPayload
) => {
@@ -157,7 +163,7 @@ const putSecret = async (
}
}
await requestWithGitHubGateway(connection, gatewayService, {
await requestWithGitHubGateway(connection, gatewayService, gatewayV2Service, {
url: `https://${await getGitHubInstanceApiUrl(connection)}${path}`,
method: "PUT",
headers: {
@@ -173,7 +179,8 @@ export const GithubSyncFns = {
syncSecrets: async (
secretSync: TGitHubSyncWithCredentials,
ogSecretMap: TSecretMap,
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">
) => {
const secretMap = Object.fromEntries(Object.entries(ogSecretMap).map(([i, v]) => [i.toUpperCase(), v]));
@@ -209,8 +216,8 @@ export const GithubSyncFns = {
? connection.credentials.accessToken
: await getGitHubAppAuthToken(connection);
const encryptedSecrets = await getEncryptedSecrets(secretSync, gatewayService);
const publicKey = await getPublicKey(secretSync, gatewayService, token);
const encryptedSecrets = await getEncryptedSecrets(secretSync, gatewayService, gatewayV2Service);
const publicKey = await getPublicKey(secretSync, gatewayService, gatewayV2Service, token);
await sodium.ready;
for await (const key of Object.keys(secretMap)) {
@@ -225,7 +232,7 @@ export const GithubSyncFns = {
const encryptedSecretValue = sodium.to_base64(encryptedBytes, sodium.base64_variants.ORIGINAL);
try {
await putSecret(secretSync, gatewayService, token, {
await putSecret(secretSync, gatewayService, gatewayV2Service, token, {
secret_name: key,
encrypted_value: encryptedSecretValue,
key_id: publicKey.key_id
@@ -246,7 +253,7 @@ export const GithubSyncFns = {
continue;
if (!(encryptedSecret.name in secretMap)) {
await deleteSecret(secretSync, gatewayService, token, encryptedSecret);
await deleteSecret(secretSync, gatewayService, gatewayV2Service, token, encryptedSecret);
}
}
},
@@ -256,7 +263,8 @@ export const GithubSyncFns = {
removeSecrets: async (
secretSync: TGitHubSyncWithCredentials,
ogSecretMap: TSecretMap,
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">
) => {
const secretMap = Object.fromEntries(Object.entries(ogSecretMap).map(([i, v]) => [i.toUpperCase(), v]));
@@ -266,11 +274,11 @@ export const GithubSyncFns = {
? connection.credentials.accessToken
: await getGitHubAppAuthToken(connection);
const encryptedSecrets = await getEncryptedSecrets(secretSync, gatewayService);
const encryptedSecrets = await getEncryptedSecrets(secretSync, gatewayService, gatewayV2Service);
for await (const encryptedSecret of encryptedSecrets) {
if (encryptedSecret.name in secretMap) {
await deleteSecret(secretSync, gatewayService, token, encryptedSecret);
await deleteSecret(secretSync, gatewayService, gatewayV2Service, token, encryptedSecret);
}
}
}
@@ -2,6 +2,7 @@ import { AxiosError } from "axios";
import handlebars from "handlebars";
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
import { TGatewayV2ServiceFactory } from "@app/ee/services/gateway-v2/gateway-v2-service";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { OCI_VAULT_SYNC_LIST_OPTION, OCIVaultSyncFns } from "@app/ee/services/secret-sync/oci-vault";
import { BadRequestError } from "@app/lib/errors";
@@ -101,6 +102,7 @@ type TSyncSecretDeps = {
appConnectionDAL: Pick<TAppConnectionDALFactory, "findById" | "update" | "updateById">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">;
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">;
};
// Add schema to secret keys
@@ -195,7 +197,7 @@ export const SecretSyncFns = {
syncSecrets: (
secretSync: TSecretSyncWithCredentials,
secretMap: TSecretMap,
{ kmsService, appConnectionDAL, gatewayService }: TSyncSecretDeps
{ kmsService, appConnectionDAL, gatewayService, gatewayV2Service }: TSyncSecretDeps
): Promise<void> => {
const schemaSecretMap = addSchema(secretMap, secretSync.environment?.slug || "", secretSync.syncOptions.keySchema);
@@ -205,7 +207,7 @@ export const SecretSyncFns = {
case SecretSync.AWSSecretsManager:
return AwsSecretsManagerSyncFns.syncSecrets(secretSync, schemaSecretMap);
case SecretSync.GitHub:
return GithubSyncFns.syncSecrets(secretSync, schemaSecretMap, gatewayService);
return GithubSyncFns.syncSecrets(secretSync, schemaSecretMap, gatewayService, gatewayV2Service);
case SecretSync.GCPSecretManager:
return GcpSyncFns.syncSecrets(secretSync, schemaSecretMap);
case SecretSync.AzureKeyVault:
@@ -404,7 +406,7 @@ export const SecretSyncFns = {
removeSecrets: (
secretSync: TSecretSyncWithCredentials,
secretMap: TSecretMap,
{ kmsService, appConnectionDAL, gatewayService }: TSyncSecretDeps
{ kmsService, appConnectionDAL, gatewayService, gatewayV2Service }: TSyncSecretDeps
): Promise<void> => {
const schemaSecretMap = addSchema(secretMap, secretSync.environment?.slug || "", secretSync.syncOptions.keySchema);
@@ -414,7 +416,7 @@ export const SecretSyncFns = {
case SecretSync.AWSSecretsManager:
return AwsSecretsManagerSyncFns.removeSecrets(secretSync, schemaSecretMap);
case SecretSync.GitHub:
return GithubSyncFns.removeSecrets(secretSync, schemaSecretMap, gatewayService);
return GithubSyncFns.removeSecrets(secretSync, schemaSecretMap, gatewayService, gatewayV2Service);
case SecretSync.GCPSecretManager:
return GcpSyncFns.removeSecrets(secretSync, schemaSecretMap);
case SecretSync.AzureKeyVault:
@@ -5,6 +5,7 @@ import { Job } from "bullmq";
import { ProjectMembershipRole, SecretType } from "@app/db/schemas";
import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types";
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
import { TGatewayV2ServiceFactory } from "@app/ee/services/gateway-v2/gateway-v2-service";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
@@ -98,6 +99,7 @@ type TSecretSyncQueueFactoryDep = {
folderCommitService: Pick<TFolderCommitServiceFactory, "createCommit">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">;
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">;
};
type SecretSyncActionJob = Job<
@@ -141,7 +143,8 @@ export const secretSyncQueueFactory = ({
resourceMetadataDAL,
folderCommitService,
licenseService,
gatewayService
gatewayService,
gatewayV2Service
}: TSecretSyncQueueFactoryDep) => {
const appCfg = getConfig();
@@ -357,7 +360,8 @@ export const secretSyncQueueFactory = ({
const importedSecrets = await SecretSyncFns.getSecrets(secretSync, {
appConnectionDAL,
kmsService,
gatewayService
gatewayService,
gatewayV2Service
});
if (!Object.keys(importedSecrets).length) return {};
@@ -486,7 +490,8 @@ export const secretSyncQueueFactory = ({
await SecretSyncFns.syncSecrets(secretSyncWithCredentials, secretMap, {
appConnectionDAL,
kmsService,
gatewayService
gatewayService,
gatewayV2Service
});
isSynced = true;
@@ -736,7 +741,8 @@ export const secretSyncQueueFactory = ({
{
appConnectionDAL,
kmsService,
gatewayService
gatewayService,
gatewayV2Service
}
);