feat: gateway registration + start of gateway v2 integration

This commit is contained in:
Sheen Capadngan
2025-08-30 05:51:07 +08:00
parent 2fb13463bc
commit 81dfcb5de1
16 changed files with 577 additions and 130 deletions

View File

@@ -101,6 +101,9 @@ import {
TGateways, TGateways,
TGatewaysInsert, TGatewaysInsert,
TGatewaysUpdate, TGatewaysUpdate,
TGatewaysV2,
TGatewaysV2Insert,
TGatewaysV2Update,
TGitAppInstallSessions, TGitAppInstallSessions,
TGitAppInstallSessionsInsert, TGitAppInstallSessionsInsert,
TGitAppInstallSessionsUpdate, TGitAppInstallSessionsUpdate,
@@ -1282,5 +1285,6 @@ declare module "knex/types/tables" {
TOrgGatewayConfigV2Update TOrgGatewayConfigV2Update
>; >;
[TableName.Proxy]: KnexOriginal.CompositeTableType<TProxies, TProxiesInsert, TProxiesUpdate>; [TableName.Proxy]: KnexOriginal.CompositeTableType<TProxies, TProxiesInsert, TProxiesUpdate>;
[TableName.GatewayV2]: KnexOriginal.CompositeTableType<TGatewaysV2, TGatewaysV2Insert, TGatewaysV2Update>;
} }
} }

View File

@@ -110,14 +110,14 @@ export async function up(knex: Knex): Promise<void> {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true); t.timestamps(true, true, true);
t.uuid("orgId"); t.uuid("orgId").notNullable();
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
t.uuid("identityId").unique(); t.uuid("identityId").notNullable().unique();
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
t.uuid("proxyId"); t.uuid("proxyId");
t.foreign("proxyId").references("id").inTable(TableName.Proxy).onDelete("CASCADE"); t.foreign("proxyId").references("id").inTable(TableName.Proxy).onDelete("SET NULL");
t.string("name").notNullable().unique(); t.string("name").notNullable().unique();
}); });
@@ -136,9 +136,9 @@ export async function down(knex: Knex): Promise<void> {
await dropOnUpdateTrigger(knex, TableName.OrgGatewayConfigV2); await dropOnUpdateTrigger(knex, TableName.OrgGatewayConfigV2);
await knex.schema.dropTableIfExists(TableName.OrgGatewayConfigV2); await knex.schema.dropTableIfExists(TableName.OrgGatewayConfigV2);
await dropOnUpdateTrigger(knex, TableName.Proxy);
await knex.schema.dropTableIfExists(TableName.Proxy);
await dropOnUpdateTrigger(knex, TableName.GatewayV2); await dropOnUpdateTrigger(knex, TableName.GatewayV2);
await knex.schema.dropTableIfExists(TableName.GatewayV2); await knex.schema.dropTableIfExists(TableName.GatewayV2);
await dropOnUpdateTrigger(knex, TableName.Proxy);
await knex.schema.dropTableIfExists(TableName.Proxy);
} }

View File

@@ -0,0 +1,22 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const GatewaysV2Schema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
orgId: z.string().uuid(),
identityId: z.string().uuid(),
proxyId: z.string().uuid().nullable().optional(),
name: z.string()
});
export type TGatewaysV2 = z.infer<typeof GatewaysV2Schema>;
export type TGatewaysV2Insert = Omit<z.input<typeof GatewaysV2Schema>, TImmutableDBKeys>;
export type TGatewaysV2Update = Partial<Omit<z.input<typeof GatewaysV2Schema>, TImmutableDBKeys>>;

View File

@@ -31,6 +31,7 @@ export * from "./folder-commits";
export * from "./folder-tree-checkpoint-resources"; export * from "./folder-tree-checkpoint-resources";
export * from "./folder-tree-checkpoints"; export * from "./folder-tree-checkpoints";
export * from "./gateways"; export * from "./gateways";
export * from "./gateways-v2";
export * from "./git-app-install-sessions"; export * from "./git-app-install-sessions";
export * from "./git-app-org"; export * from "./git-app-org";
export * from "./github-org-sync-configs"; export * from "./github-org-sync-configs";
@@ -98,6 +99,7 @@ export * from "./project-templates";
export * from "./project-user-additional-privilege"; export * from "./project-user-additional-privilege";
export * from "./project-user-membership-roles"; export * from "./project-user-membership-roles";
export * from "./projects"; export * from "./projects";
export * from "./proxies";
export * from "./rate-limit"; export * from "./rate-limit";
export * from "./resource-metadata"; export * from "./resource-metadata";
export * from "./saml-configs"; export * from "./saml-configs";
@@ -165,4 +167,3 @@ export * from "./user-group-membership";
export * from "./users"; export * from "./users";
export * from "./webhooks"; export * from "./webhooks";
export * from "./workflow-integrations"; export * from "./workflow-integrations";
export * from "./proxies";

View File

@@ -7,23 +7,43 @@ export const registerGatewayV2Router = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "POST", method: "POST",
url: "/", url: "/",
onRequest: verifyAuth([AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: { schema: {
body: z.object({ body: z.object({
proxyName: z.string() proxyName: z.string(),
name: z.string()
}), }),
response: { response: {
200: z.any() 200: z.any()
} }
}, },
onRequest: verifyAuth([AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const gateway = await server.services.gatewayV2.registerGateway({ const gateway = await server.services.gatewayV2.registerGateway({
orgId: req.permission.orgId, orgId: req.permission.orgId,
proxyName: req.body.proxyName, proxyName: req.body.proxyName,
actorId: req.permission.id actorId: req.permission.id,
name: req.body.name
}); });
return gateway; return gateway;
} }
}); });
server.route({
method: "GET",
url: "/",
schema: {
response: {
200: z.any()
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const gateways = await server.services.gatewayV2.listGateways({
orgPermission: req.permission
});
return gateways;
}
});
}; };

View File

@@ -19,6 +19,7 @@ import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-fold
import { TDynamicSecretLeaseDALFactory } from "../dynamic-secret-lease/dynamic-secret-lease-dal"; import { TDynamicSecretLeaseDALFactory } from "../dynamic-secret-lease/dynamic-secret-lease-dal";
import { TDynamicSecretLeaseQueueServiceFactory } from "../dynamic-secret-lease/dynamic-secret-lease-queue"; import { TDynamicSecretLeaseQueueServiceFactory } from "../dynamic-secret-lease/dynamic-secret-lease-queue";
import { TGatewayDALFactory } from "../gateway/gateway-dal"; import { TGatewayDALFactory } from "../gateway/gateway-dal";
import { TGatewayV2DALFactory } from "../gateway-v2/gateway-v2-dal";
import { OrgPermissionGatewayActions, OrgPermissionSubjects } from "../permission/org-permission"; import { OrgPermissionGatewayActions, OrgPermissionSubjects } from "../permission/org-permission";
import { TDynamicSecretDALFactory } from "./dynamic-secret-dal"; import { TDynamicSecretDALFactory } from "./dynamic-secret-dal";
import { DynamicSecretStatus, TDynamicSecretServiceFactory } from "./dynamic-secret-types"; import { DynamicSecretStatus, TDynamicSecretServiceFactory } from "./dynamic-secret-types";
@@ -39,6 +40,7 @@ type TDynamicSecretServiceFactoryDep = {
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">; kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
gatewayDAL: Pick<TGatewayDALFactory, "findOne" | "find">; gatewayDAL: Pick<TGatewayDALFactory, "findOne" | "find">;
gatewayV2DAL: Pick<TGatewayV2DALFactory, "findOne" | "find">;
resourceMetadataDAL: Pick<TResourceMetadataDALFactory, "insertMany" | "delete">; resourceMetadataDAL: Pick<TResourceMetadataDALFactory, "insertMany" | "delete">;
}; };
@@ -53,6 +55,7 @@ export const dynamicSecretServiceFactory = ({
projectDAL, projectDAL,
kmsService, kmsService,
gatewayDAL, gatewayDAL,
gatewayV2DAL,
resourceMetadataDAL resourceMetadataDAL
}: TDynamicSecretServiceFactoryDep): TDynamicSecretServiceFactory => { }: TDynamicSecretServiceFactoryDep): TDynamicSecretServiceFactory => {
const create: TDynamicSecretServiceFactory["create"] = async ({ const create: TDynamicSecretServiceFactory["create"] = async ({
@@ -118,8 +121,9 @@ export const dynamicSecretServiceFactory = ({
const gatewayId = inputs.gatewayId as string; const gatewayId = inputs.gatewayId as string;
const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: actorOrgId }); const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: actorOrgId });
const [gatewayv2] = await gatewayV2DAL.find({ id: gatewayId, orgId: actorOrgId });
if (!gateway) { if (!gateway && !gatewayv2) {
throw new NotFoundError({ throw new NotFoundError({
message: `Gateway with ID ${gatewayId} not found` message: `Gateway with ID ${gatewayId} not found`
}); });
@@ -128,7 +132,7 @@ export const dynamicSecretServiceFactory = ({
const { permission: orgPermission } = await permissionService.getOrgPermission( const { permission: orgPermission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
gateway.orgId, gateway?.orgId ?? gatewayv2?.orgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -138,7 +142,7 @@ export const dynamicSecretServiceFactory = ({
OrgPermissionSubjects.Gateway OrgPermissionSubjects.Gateway
); );
selectedGatewayId = gateway.id; selectedGatewayId = gateway?.id ?? gatewayv2?.id;
} }
const isConnected = await selectedProvider.validateConnection(provider.inputs, { projectId }); const isConnected = await selectedProvider.validateConnection(provider.inputs, { projectId });

View File

@@ -1,6 +1,7 @@
import { SnowflakeProvider } from "@app/ee/services/dynamic-secret/providers/snowflake"; import { SnowflakeProvider } from "@app/ee/services/dynamic-secret/providers/snowflake";
import { TGatewayServiceFactory } from "../../gateway/gateway-service"; import { TGatewayServiceFactory } from "../../gateway/gateway-service";
import { TGatewayV2ServiceFactory } from "../../gateway-v2/gateway-v2-service";
import { AwsElastiCacheDatabaseProvider } from "./aws-elasticache"; import { AwsElastiCacheDatabaseProvider } from "./aws-elasticache";
import { AwsIamProvider } from "./aws-iam"; import { AwsIamProvider } from "./aws-iam";
import { AzureEntraIDProvider } from "./azure-entra-id"; import { AzureEntraIDProvider } from "./azure-entra-id";
@@ -24,10 +25,12 @@ import { VerticaProvider } from "./vertica";
type TBuildDynamicSecretProviderDTO = { type TBuildDynamicSecretProviderDTO = {
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">; gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">;
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">;
}; };
export const buildDynamicSecretProviders = ({ export const buildDynamicSecretProviders = ({
gatewayService gatewayService,
gatewayV2Service
}: TBuildDynamicSecretProviderDTO): Record<DynamicSecretProviders, TDynamicProviderFns> => ({ }: TBuildDynamicSecretProviderDTO): Record<DynamicSecretProviders, TDynamicProviderFns> => ({
[DynamicSecretProviders.SqlDatabase]: SqlDatabaseProvider({ gatewayService }), [DynamicSecretProviders.SqlDatabase]: SqlDatabaseProvider({ gatewayService }),
[DynamicSecretProviders.Cassandra]: CassandraProvider(), [DynamicSecretProviders.Cassandra]: CassandraProvider(),
@@ -44,7 +47,7 @@ export const buildDynamicSecretProviders = ({
[DynamicSecretProviders.Snowflake]: SnowflakeProvider(), [DynamicSecretProviders.Snowflake]: SnowflakeProvider(),
[DynamicSecretProviders.Totp]: TotpProvider(), [DynamicSecretProviders.Totp]: TotpProvider(),
[DynamicSecretProviders.SapAse]: SapAseProvider(), [DynamicSecretProviders.SapAse]: SapAseProvider(),
[DynamicSecretProviders.Kubernetes]: KubernetesProvider({ gatewayService }), [DynamicSecretProviders.Kubernetes]: KubernetesProvider({ gatewayService, gatewayV2Service }),
[DynamicSecretProviders.Vertica]: VerticaProvider({ gatewayService }), [DynamicSecretProviders.Vertica]: VerticaProvider({ gatewayService }),
[DynamicSecretProviders.GcpIam]: GcpIamProvider(), [DynamicSecretProviders.GcpIam]: GcpIamProvider(),
[DynamicSecretProviders.Github]: GithubProvider(), [DynamicSecretProviders.Github]: GithubProvider(),

View File

@@ -5,12 +5,14 @@ import https from "https";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { sanitizeString } from "@app/lib/fn"; import { sanitizeString } from "@app/lib/fn";
import { GatewayHttpProxyActions, GatewayProxyProtocol, withGatewayProxy } from "@app/lib/gateway"; import { GatewayHttpProxyActions, GatewayProxyProtocol, withGatewayProxy } from "@app/lib/gateway";
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
import { alphaNumericNanoId } from "@app/lib/nanoid"; import { alphaNumericNanoId } from "@app/lib/nanoid";
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator"; import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
import { TKubernetesTokenRequest } from "@app/services/identity-kubernetes-auth/identity-kubernetes-auth-types"; import { TKubernetesTokenRequest } from "@app/services/identity-kubernetes-auth/identity-kubernetes-auth-types";
import { TDynamicSecretKubernetesLeaseConfig } from "../../dynamic-secret-lease/dynamic-secret-lease-types"; import { TDynamicSecretKubernetesLeaseConfig } from "../../dynamic-secret-lease/dynamic-secret-lease-types";
import { TGatewayServiceFactory } from "../../gateway/gateway-service"; import { TGatewayServiceFactory } from "../../gateway/gateway-service";
import { TGatewayV2ServiceFactory } from "../../gateway-v2/gateway-v2-service";
import { import {
DynamicSecretKubernetesSchema, DynamicSecretKubernetesSchema,
KubernetesAuthMethod, KubernetesAuthMethod,
@@ -26,6 +28,7 @@ const GATEWAY_AUTH_DEFAULT_URL = "https://kubernetes.default.svc.cluster.local";
type TKubernetesProviderDTO = { type TKubernetesProviderDTO = {
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">; gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">;
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">;
}; };
const generateUsername = (usernameTemplate?: string | null) => { const generateUsername = (usernameTemplate?: string | null) => {
@@ -38,7 +41,10 @@ const generateUsername = (usernameTemplate?: string | null) => {
}); });
}; };
export const KubernetesProvider = ({ gatewayService }: TKubernetesProviderDTO): TDynamicProviderFns => { export const KubernetesProvider = ({
gatewayService,
gatewayV2Service
}: TKubernetesProviderDTO): TDynamicProviderFns => {
const validateProviderInputs = async (inputs: unknown) => { const validateProviderInputs = async (inputs: unknown) => {
const providerInputs = await DynamicSecretKubernetesSchema.parseAsync(inputs); const providerInputs = await DynamicSecretKubernetesSchema.parseAsync(inputs);
if (!providerInputs.gatewayId && providerInputs.url) { if (!providerInputs.gatewayId && providerInputs.url) {
@@ -58,6 +64,26 @@ export const KubernetesProvider = ({ gatewayService }: TKubernetesProviderDTO):
}, },
gatewayCallback: (host: string, port: number, httpsAgent?: https.Agent) => Promise<T> gatewayCallback: (host: string, port: number, httpsAgent?: https.Agent) => Promise<T>
): Promise<T> => { ): Promise<T> => {
const gatewayV2ConnectionDetails = await gatewayV2Service.getPlatformConnectionDetailsByGatewayId(inputs.gatewayId);
if (gatewayV2ConnectionDetails) {
const callbackResult = await withGatewayV2Proxy(
async (port) => {
return gatewayCallback(
inputs.reviewTokenThroughGateway ? "http://localhost" : "https://localhost",
port,
inputs.httpsAgent
);
},
{
proxyIp: gatewayV2ConnectionDetails.proxyIp,
gateway: gatewayV2ConnectionDetails.gateway,
proxy: gatewayV2ConnectionDetails.proxy
}
);
return callbackResult;
}
const relayDetails = await gatewayService.fnGetGatewayClientTlsByGatewayId(inputs.gatewayId); const relayDetails = await gatewayService.fnGetGatewayClientTlsByGatewayId(inputs.gatewayId);
const [relayHost, relayPort] = relayDetails.relayAddress.split(":"); const [relayHost, relayPort] = relayDetails.relayAddress.split(":");

View File

@@ -0,0 +1,11 @@
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { ormify } from "@app/lib/knex";
export type TGatewayV2DALFactory = ReturnType<typeof gatewayV2DalFactory>;
export const gatewayV2DalFactory = (db: TDbClient) => {
const orm = ormify(db, TableName.GatewayV2);
return orm;
};

View File

@@ -1,7 +1,11 @@
import * as x509 from "@peculiar/x509"; import * as x509 from "@peculiar/x509";
import { TProxies } from "@app/db/schemas";
import { PgSqlLock } from "@app/keystore/keystore"; import { PgSqlLock } from "@app/keystore/keystore";
import { crypto } from "@app/lib/crypto"; import { crypto } from "@app/lib/crypto";
import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { OrgServiceActor } from "@app/lib/types";
import { ActorType } from "@app/services/auth/auth-type";
import { constructPemChainFromCerts } from "@app/services/certificate/certificate-fns"; import { constructPemChainFromCerts } from "@app/services/certificate/certificate-fns";
import { CertExtendedKeyUsage, CertKeyAlgorithm, CertKeyUsage } from "@app/services/certificate/certificate-types"; import { CertExtendedKeyUsage, CertKeyAlgorithm, CertKeyUsage } from "@app/services/certificate/certificate-types";
import { import {
@@ -11,13 +15,18 @@ import {
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { KmsDataKey } from "@app/services/kms/kms-types"; import { KmsDataKey } from "@app/services/kms/kms-types";
import { TProxyDALFactory } from "../proxy/proxy-dal";
import { isInstanceProxy } from "../proxy/proxy-fns";
import { TProxyServiceFactory } from "../proxy/proxy-service"; import { TProxyServiceFactory } from "../proxy/proxy-service";
import { TGatewayV2DALFactory } from "./gateway-v2-dal";
import { TOrgGatewayConfigV2DALFactory } from "./org-gateway-config-v2-dal"; import { TOrgGatewayConfigV2DALFactory } from "./org-gateway-config-v2-dal";
type TGatewayV2ServiceFactoryDep = { type TGatewayV2ServiceFactoryDep = {
orgGatewayConfigV2DAL: Pick<TOrgGatewayConfigV2DALFactory, "findOne" | "create" | "transaction" | "findById">; orgGatewayConfigV2DAL: Pick<TOrgGatewayConfigV2DALFactory, "findOne" | "create" | "transaction" | "findById">;
kmsService: TKmsServiceFactory; kmsService: TKmsServiceFactory;
proxyService: TProxyServiceFactory; proxyService: TProxyServiceFactory;
gatewayV2DAL: TGatewayV2DALFactory;
proxyDAL: TProxyDALFactory;
}; };
export type TGatewayV2ServiceFactory = ReturnType<typeof gatewayV2ServiceFactory>; export type TGatewayV2ServiceFactory = ReturnType<typeof gatewayV2ServiceFactory>;
@@ -25,7 +34,9 @@ export type TGatewayV2ServiceFactory = ReturnType<typeof gatewayV2ServiceFactory
export const gatewayV2ServiceFactory = ({ export const gatewayV2ServiceFactory = ({
orgGatewayConfigV2DAL, orgGatewayConfigV2DAL,
kmsService, kmsService,
proxyService proxyService,
gatewayV2DAL,
proxyDAL
}: TGatewayV2ServiceFactoryDep) => { }: TGatewayV2ServiceFactoryDep) => {
const $getOrgCAs = async (orgId: string) => { const $getOrgCAs = async (orgId: string) => {
const { encryptor: orgKmsEncryptor, decryptor: orgKmsDecryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor: orgKmsEncryptor, decryptor: orgKmsDecryptor } = await kmsService.createCipherPairWithDataKey({
@@ -197,11 +208,179 @@ export const gatewayV2ServiceFactory = ({
}; };
}; };
const registerGateway = async ({ orgId, proxyName }: { orgId: string; actorId: string; proxyName: string }) => { const listGateways = async ({ orgPermission }: { orgPermission: OrgServiceActor }) => {
// const { permission } = await permissionService.getOrgPermission(
// orgPermission.type,
// orgPermission.id,
// orgPermission.orgId,
// orgPermission.authMethod,
// orgPermission.orgId
// );
// ForbiddenError.from(permission).throwUnlessCan(
// OrgPermissionGatewayActions.ListGateways,
// OrgPermissionSubjects.Gateway
// );
const orgGatewayConfig = await orgGatewayConfigV2DAL.findOne({ orgId: orgPermission.orgId });
if (!orgGatewayConfig) return [];
const gateways = await gatewayV2DAL.find({
orgId: orgPermission.orgId
});
return gateways;
};
const getPlatformConnectionDetailsByGatewayId = async (gatewayId: string) => {
const gateway = await gatewayV2DAL.findById(gatewayId);
if (!gateway) {
return;
}
const orgGatewayConfig = await orgGatewayConfigV2DAL.findOne({ orgId: gateway.orgId });
if (!orgGatewayConfig) {
throw new NotFoundError({ message: `Gateway Config for org ${gateway.orgId} not found.` });
}
if (!gateway.proxyId) {
throw new BadRequestError({
message: "Gateway is not associated with a proxy"
});
}
// const orgLicensePlan = await licenseService.getPlan(orgGatewayConfig.orgId);
// if (!orgLicensePlan.gateway) {
// throw new BadRequestError({
// message: "Please upgrade your instance to Infisical's Enterprise plan to use gateways."
// });
// }
const { decryptor: orgKmsDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization,
orgId: orgGatewayConfig.orgId
});
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
const rootGatewayCaCert = new x509.X509Certificate(
orgKmsDecryptor({
cipherTextBlob: orgGatewayConfig.encryptedRootGatewayCaCertificate
})
);
const gatewayClientCaCert = new x509.X509Certificate(
orgKmsDecryptor({
cipherTextBlob: orgGatewayConfig.encryptedGatewayClientCaCertificate
})
);
const gatewayClientCaPrivateKey = orgKmsDecryptor({
cipherTextBlob: orgGatewayConfig.encryptedGatewayClientCaPrivateKey
});
const gatewayClientCaSkObj = crypto.nativeCrypto.createPrivateKey({
key: gatewayClientCaPrivateKey,
format: "der",
type: "pkcs8"
});
const importedGatewayClientCaPrivateKey = await crypto.nativeCrypto.subtle.importKey(
"pkcs8",
gatewayClientCaSkObj.export({ format: "der", type: "pkcs8" }),
alg,
true,
["sign"]
);
const clientCertIssuedAt = new Date();
const clientCertExpiration = new Date(new Date().getTime() + 5 * 60 * 1000);
const clientKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
const clientCertSerialNumber = createSerialNumber();
const clientCert = await x509.X509CertificateGenerator.create({
serialNumber: clientCertSerialNumber,
subject: `O=${orgGatewayConfig.orgId},OU=gateway-client,CN=${ActorType.PLATFORM}:${gatewayId}`,
issuer: gatewayClientCaCert.subject,
notAfter: clientCertExpiration,
notBefore: clientCertIssuedAt,
signingKey: importedGatewayClientCaPrivateKey,
publicKey: clientKeys.publicKey,
signingAlgorithm: alg,
extensions: [
new x509.BasicConstraintsExtension(false),
await x509.AuthorityKeyIdentifierExtension.create(gatewayClientCaCert, false),
await x509.SubjectKeyIdentifierExtension.create(clientKeys.publicKey),
new x509.CertificatePolicyExtension(["2.5.29.32.0"]), // anyPolicy
new x509.KeyUsagesExtension(
// eslint-disable-next-line no-bitwise
x509.KeyUsageFlags[CertKeyUsage.DIGITAL_SIGNATURE] |
x509.KeyUsageFlags[CertKeyUsage.KEY_ENCIPHERMENT] |
x509.KeyUsageFlags[CertKeyUsage.KEY_AGREEMENT],
true
),
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.CLIENT_AUTH]], true)
]
});
const gatewayClientCertPrivateKey = crypto.nativeCrypto.KeyObject.from(clientKeys.privateKey);
const proxyCredentials = await proxyService.getCredentialsForClient({
proxyId: gateway.proxyId,
orgId: gateway.orgId,
gatewayId,
actor: ActorType.PLATFORM
});
return {
proxyIp: proxyCredentials.proxyIp,
gateway: {
clientCertificate: clientCert.toString("pem"),
clientPrivateKey: gatewayClientCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
clientCertificateChain: constructPemChainFromCerts([gatewayClientCaCert, rootGatewayCaCert]),
serverCA: rootGatewayCaCert.toString("pem")
},
proxy: {
clientCertificate: proxyCredentials.clientCertificate,
clientPrivateKey: proxyCredentials.clientPrivateKey,
serverCertificateChain: proxyCredentials.serverCertificateChain
}
};
};
const registerGateway = async ({
orgId,
actorId,
proxyName,
name
}: {
orgId: string;
actorId: string;
proxyName: string;
name: string;
}) => {
const orgCAs = await $getOrgCAs(orgId); const orgCAs = await $getOrgCAs(orgId);
// TODO: Save gateway to DB and set Gateway ID as principal in SSH certificate let proxy: TProxies;
// only throw error if proxy is different from existing DB record if (isInstanceProxy(proxyName)) {
proxy = await proxyDAL.findOne({ name: proxyName });
} else {
proxy = await proxyDAL.findOne({ orgId, name: proxyName });
}
if (!proxy) {
throw new Error("Proxy not found");
}
const [gateway] = await gatewayV2DAL.upsert(
[
{
orgId,
name,
identityId: actorId,
proxyId: proxy.id
}
],
["identityId"]
);
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048); const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
const gatewayServerCaCert = new x509.X509Certificate(orgCAs.gatewayServerCaCertificate); const gatewayServerCaCert = new x509.X509Certificate(orgCAs.gatewayServerCaCertificate);
@@ -253,11 +432,12 @@ export const gatewayV2ServiceFactory = ({
const proxyCredentials = await proxyService.getCredentialsForGateway({ const proxyCredentials = await proxyService.getCredentialsForGateway({
proxyName, proxyName,
orgId orgId,
gatewayId: gateway.id
}); });
return { return {
// TODO: return gateway ID gatewayId: gateway.id,
proxyIp: proxyCredentials.proxyIp, proxyIp: proxyCredentials.proxyIp,
pki: { pki: {
serverCertificate: gatewayServerCertificate.toString("pem"), serverCertificate: gatewayServerCertificate.toString("pem"),
@@ -274,6 +454,8 @@ export const gatewayV2ServiceFactory = ({
}; };
return { return {
registerGateway listGateways,
registerGateway,
getPlatformConnectionDetailsByGatewayId
}; };
}; };

View File

@@ -4,6 +4,7 @@ import { TProxies } from "@app/db/schemas";
import { PgSqlLock } from "@app/keystore/keystore"; import { PgSqlLock } from "@app/keystore/keystore";
import { crypto } from "@app/lib/crypto"; import { crypto } from "@app/lib/crypto";
import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { ActorType } from "@app/services/auth/auth-type";
import { constructPemChainFromCerts, prependCertToPemChain } from "@app/services/certificate/certificate-fns"; import { constructPemChainFromCerts, prependCertToPemChain } from "@app/services/certificate/certificate-fns";
import { CertExtendedKeyUsage, CertKeyAlgorithm, CertKeyUsage } from "@app/services/certificate/certificate-types"; import { CertExtendedKeyUsage, CertKeyAlgorithm, CertKeyUsage } from "@app/services/certificate/certificate-types";
import { import {
@@ -89,7 +90,7 @@ export const proxyServiceFactory = ({
x509.KeyUsageFlags.keyEncipherment, x509.KeyUsageFlags.keyEncipherment,
true true
), ),
new x509.BasicConstraintsExtension(true, 0, true), new x509.BasicConstraintsExtension(true, 2, true),
await x509.AuthorityKeyIdentifierExtension.create(rootCaCert, false), await x509.AuthorityKeyIdentifierExtension.create(rootCaCert, false),
await x509.SubjectKeyIdentifierExtension.create(orgProxyCaKeys.publicKey) await x509.SubjectKeyIdentifierExtension.create(orgProxyCaKeys.publicKey)
] ]
@@ -120,7 +121,7 @@ export const proxyServiceFactory = ({
x509.KeyUsageFlags.keyEncipherment, x509.KeyUsageFlags.keyEncipherment,
true true
), ),
new x509.BasicConstraintsExtension(true, 0, true), new x509.BasicConstraintsExtension(true, 1, true),
await x509.AuthorityKeyIdentifierExtension.create(rootCaCert, false), await x509.AuthorityKeyIdentifierExtension.create(rootCaCert, false),
await x509.SubjectKeyIdentifierExtension.create(instanceProxyCaKeys.publicKey) await x509.SubjectKeyIdentifierExtension.create(instanceProxyCaKeys.publicKey)
] ]
@@ -587,88 +588,28 @@ export const proxyServiceFactory = ({
}; };
}; };
const getCredentialsForGateway = async ({ proxyName, orgId }: { proxyName: string; orgId: string }) => { const $generateProxyServerCredentials = async ({
let proxy: TProxies | null;
if (isInstanceProxy(proxyName)) {
proxy = await proxyDAL.findOne({
name: proxyName
});
} else {
proxy = await proxyDAL.findOne({
orgId,
name: proxyName
});
}
if (!proxy) {
throw new NotFoundError({
message: "Proxy not found"
});
}
const keyAlgorithm = SshCertKeyAlgorithm.RSA_2048;
const { publicKey: proxyClientSshPublicKey, privateKey: proxyClientSshPrivateKey } =
await createSshKeyPair(keyAlgorithm);
if (isInstanceProxy(proxyName)) {
const instanceCAs = await $getInstanceCAs();
const proxyClientSshCert = await createSshCert({
caPrivateKey: instanceCAs.instanceProxySshServerCaPrivateKey.toString("utf8"),
clientPublicKey: proxyClientSshPublicKey,
keyId: `proxy-client-${proxy.id}`,
principals: ["gateway ID"], // TODO: set gateway ID as principal in SSH certificate
certType: SshCertType.USER,
requestedTtl: "30d"
});
return {
proxyIp: proxy.ip,
clientSshCert: proxyClientSshCert.signedPublicKey,
clientSshPrivateKey: proxyClientSshPrivateKey,
serverCAPublicKey: instanceCAs.instanceProxySshServerCaPublicKey.toString("utf8")
};
}
const orgCAs = await $getOrgCAs(orgId);
const proxyClientSshCert = await createSshCert({
caPrivateKey: orgCAs.proxySshServerCaPrivateKey.toString("utf8"),
clientPublicKey: proxyClientSshPublicKey,
keyId: `proxy-client-${proxy.id}`,
principals: [orgId],
certType: SshCertType.USER,
requestedTtl: "30d"
});
return {
proxyIp: proxy.ip,
clientSshCert: proxyClientSshCert.signedPublicKey,
clientSshPrivateKey: proxyClientSshPrivateKey,
serverCAPublicKey: orgCAs.proxySshServerCaPublicKey.toString("utf8")
};
};
const $generateProxyCredentials = async ({
ip, ip,
orgId, orgId,
rootProxyPkiCaCertificate,
proxyPkiServerCaCertificate, proxyPkiServerCaCertificate,
proxyPkiServerCaPrivateKey, proxyPkiServerCaPrivateKey,
proxySshServerCaPrivateKey, proxyPkiClientCaCertificate,
proxyPkiServerCaCertificateChain, proxyPkiClientCaCertificateChain,
proxySshClientCaPublicKey proxySshClientCaPublicKey,
proxySshServerCaPrivateKey
}: { }: {
ip: string; ip: string;
rootProxyPkiCaCertificate: Buffer;
proxyPkiServerCaCertificate: Buffer; proxyPkiServerCaCertificate: Buffer;
proxyPkiServerCaPrivateKey: Buffer; proxyPkiServerCaPrivateKey: Buffer;
proxyPkiClientCaCertificateChain: Buffer;
proxyPkiClientCaCertificate: Buffer;
proxySshServerCaPrivateKey: Buffer; proxySshServerCaPrivateKey: Buffer;
proxyPkiServerCaCertificateChain: Buffer;
proxySshClientCaPublicKey: Buffer; proxySshClientCaPublicKey: Buffer;
orgId?: string; orgId?: string;
}) => { }) => {
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048); const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
const proxyServerCaCert = new x509.X509Certificate(proxyPkiServerCaCertificate); const proxyServerCaCert = new x509.X509Certificate(proxyPkiServerCaCertificate);
const rootProxyCaCert = new x509.X509Certificate(rootProxyPkiCaCertificate); const proxyClientCaCert = new x509.X509Certificate(proxyPkiClientCaCertificate);
const proxyServerCaSkObj = crypto.nativeCrypto.createPrivateKey({ const proxyServerCaSkObj = crypto.nativeCrypto.createPrivateKey({
key: proxyPkiServerCaPrivateKey, key: proxyPkiServerCaPrivateKey,
format: "der", format: "der",
@@ -733,12 +674,11 @@ export const proxyServiceFactory = ({
return { return {
pki: { pki: {
serverCertificate: proxyServerCertificate.toString("pem"), serverCertificate: proxyServerCertificate.toString("pem"),
serverCertificateChain: prependCertToPemChain(
proxyServerCaCert,
proxyPkiServerCaCertificateChain.toString("utf8")
),
serverPrivateKey: proxyServerCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(), serverPrivateKey: proxyServerCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
clientCA: rootProxyCaCert.toString("pem") clientCertificateChain: prependCertToPemChain(
proxyClientCaCert,
proxyPkiClientCaCertificateChain.toString("utf8")
)
}, },
ssh: { ssh: {
serverCertificate: proxyServerSshCert.signedPublicKey, serverCertificate: proxyServerSshCert.signedPublicKey,
@@ -748,6 +688,205 @@ export const proxyServiceFactory = ({
}; };
}; };
const $generateProxyClientCredentials = async ({
actor,
gatewayId,
orgId,
proxyPkiClientCaCertificate,
proxyPkiClientCaPrivateKey,
proxyPkiServerCaCertificate,
proxyPkiServerCaCertificateChain
}: {
actor: ActorType;
gatewayId: string;
orgId: string;
proxyPkiClientCaCertificate: Buffer;
proxyPkiClientCaPrivateKey: Buffer;
proxyPkiServerCaCertificate: Buffer;
proxyPkiServerCaCertificateChain: Buffer;
}) => {
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
const proxyClientCaCert = new x509.X509Certificate(proxyPkiClientCaCertificate);
const proxyServerCaCert = new x509.X509Certificate(proxyPkiServerCaCertificate);
const proxyClientCaSkObj = crypto.nativeCrypto.createPrivateKey({
key: proxyPkiClientCaPrivateKey,
format: "der",
type: "pkcs8"
});
const importedProxyClientCaPrivateKey = await crypto.nativeCrypto.subtle.importKey(
"pkcs8",
proxyClientCaSkObj.export({ format: "der", type: "pkcs8" }),
alg,
true,
["sign"]
);
const clientCertIssuedAt = new Date();
const clientCertExpiration = new Date(new Date().getTime() + 5 * 60 * 1000);
const clientKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
const clientCertPrivateKey = crypto.nativeCrypto.KeyObject.from(clientKeys.privateKey);
const clientCertSerialNumber = createSerialNumber();
const clientCert = await x509.X509CertificateGenerator.create({
serialNumber: clientCertSerialNumber,
subject: `O=${orgId},OU=proxy-client,CN=${actor}:${gatewayId}`,
issuer: proxyClientCaCert.subject,
notAfter: clientCertExpiration,
notBefore: clientCertIssuedAt,
signingKey: importedProxyClientCaPrivateKey,
publicKey: clientKeys.publicKey,
signingAlgorithm: alg,
extensions: [
new x509.BasicConstraintsExtension(false),
await x509.AuthorityKeyIdentifierExtension.create(proxyClientCaCert, false),
await x509.SubjectKeyIdentifierExtension.create(clientKeys.publicKey),
new x509.CertificatePolicyExtension(["2.5.29.32.0"]), // anyPolicy
new x509.KeyUsagesExtension(
// eslint-disable-next-line no-bitwise
x509.KeyUsageFlags[CertKeyUsage.DIGITAL_SIGNATURE] |
x509.KeyUsageFlags[CertKeyUsage.KEY_ENCIPHERMENT] |
x509.KeyUsageFlags[CertKeyUsage.KEY_AGREEMENT],
true
),
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.CLIENT_AUTH]], true)
]
});
return {
clientCertificate: clientCert.toString("pem"),
clientPrivateKey: clientCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
serverCertificateChain: prependCertToPemChain(
proxyServerCaCert,
proxyPkiServerCaCertificateChain.toString("utf8")
)
};
};
const getCredentialsForGateway = async ({
proxyName,
orgId,
gatewayId
}: {
proxyName: string;
orgId: string;
gatewayId: string;
}) => {
let proxy: TProxies | null;
if (isInstanceProxy(proxyName)) {
proxy = await proxyDAL.findOne({
name: proxyName
});
} else {
proxy = await proxyDAL.findOne({
orgId,
name: proxyName
});
}
if (!proxy) {
throw new NotFoundError({
message: "Proxy not found"
});
}
const keyAlgorithm = SshCertKeyAlgorithm.RSA_2048;
const { publicKey: proxyClientSshPublicKey, privateKey: proxyClientSshPrivateKey } =
await createSshKeyPair(keyAlgorithm);
if (isInstanceProxy(proxyName)) {
const instanceCAs = await $getInstanceCAs();
const proxyClientSshCert = await createSshCert({
caPrivateKey: instanceCAs.instanceProxySshServerCaPrivateKey.toString("utf8"),
clientPublicKey: proxyClientSshPublicKey,
keyId: `proxy-client-${proxy.id}`,
principals: [gatewayId],
certType: SshCertType.USER,
requestedTtl: "30d"
});
return {
proxyIp: proxy.ip,
clientSshCert: proxyClientSshCert.signedPublicKey,
clientSshPrivateKey: proxyClientSshPrivateKey,
serverCAPublicKey: instanceCAs.instanceProxySshServerCaPublicKey.toString("utf8")
};
}
const orgCAs = await $getOrgCAs(orgId);
const proxyClientSshCert = await createSshCert({
caPrivateKey: orgCAs.proxySshServerCaPrivateKey.toString("utf8"),
clientPublicKey: proxyClientSshPublicKey,
keyId: `proxy-client-${proxy.id}`,
principals: [gatewayId],
certType: SshCertType.USER,
requestedTtl: "30d"
});
return {
proxyIp: proxy.ip,
clientSshCert: proxyClientSshCert.signedPublicKey,
clientSshPrivateKey: proxyClientSshPrivateKey,
serverCAPublicKey: orgCAs.proxySshServerCaPublicKey.toString("utf8")
};
};
const getCredentialsForClient = async ({
proxyId,
orgId,
gatewayId,
actor
}: {
proxyId: string;
orgId: string;
gatewayId: string;
actor: ActorType;
}) => {
const proxy = await proxyDAL.findOne({
id: proxyId
});
if (!proxy) {
throw new NotFoundError({
message: "Proxy not found"
});
}
if (isInstanceProxy(proxy.name)) {
const instanceCAs = await $getInstanceCAs();
const proxyCertificateCredentials = await $generateProxyClientCredentials({
actor,
gatewayId,
orgId,
proxyPkiClientCaCertificate: instanceCAs.instanceProxyPkiClientCaCertificate,
proxyPkiClientCaPrivateKey: instanceCAs.instanceProxyPkiClientCaPrivateKey,
proxyPkiServerCaCertificate: instanceCAs.instanceProxyPkiServerCaCertificate,
proxyPkiServerCaCertificateChain: instanceCAs.instanceProxyPkiServerCaCertificateChain
});
return {
...proxyCertificateCredentials,
proxyIp: proxy.ip
};
}
const orgCAs = await $getOrgCAs(orgId);
const proxyCertificateCredentials = await $generateProxyClientCredentials({
actor,
gatewayId,
orgId,
proxyPkiClientCaCertificate: orgCAs.proxyPkiClientCaCertificate,
proxyPkiClientCaPrivateKey: orgCAs.proxyPkiClientCaPrivateKey,
proxyPkiServerCaCertificate: orgCAs.proxyPkiServerCaCertificate,
proxyPkiServerCaCertificateChain: orgCAs.proxyPkiServerCaCertificateChain
});
return {
...proxyCertificateCredentials,
proxyIp: proxy.ip
};
};
const registerProxy = async ({ const registerProxy = async ({
ip, ip,
name, name,
@@ -837,14 +976,12 @@ export const proxyServiceFactory = ({
if (isInstanceProxy(name)) { if (isInstanceProxy(name)) {
const instanceCAs = await $getInstanceCAs(); const instanceCAs = await $getInstanceCAs();
return $generateProxyCredentials({ return $generateProxyServerCredentials({
ip, ip,
rootProxyPkiCaCertificate: instanceCAs.rootProxyPkiCaCertificate,
proxyPkiServerCaCertificate: instanceCAs.instanceProxyPkiServerCaCertificate, proxyPkiServerCaCertificate: instanceCAs.instanceProxyPkiServerCaCertificate,
proxyPkiServerCaPrivateKey: instanceCAs.instanceProxyPkiServerCaPrivateKey, proxyPkiServerCaPrivateKey: instanceCAs.instanceProxyPkiServerCaPrivateKey,
proxyPkiServerCaCertificateChain: instanceCAs.instanceProxyPkiServerCaCertificateChain, proxyPkiClientCaCertificate: instanceCAs.instanceProxyPkiClientCaCertificate,
proxyPkiClientCaCertificateChain: instanceCAs.instanceProxyPkiClientCaCertificateChain,
proxySshServerCaPrivateKey: instanceCAs.instanceProxySshServerCaPrivateKey, proxySshServerCaPrivateKey: instanceCAs.instanceProxySshServerCaPrivateKey,
proxySshClientCaPublicKey: instanceCAs.instanceProxySshClientCaPublicKey proxySshClientCaPublicKey: instanceCAs.instanceProxySshClientCaPublicKey
}); });
@@ -852,17 +989,13 @@ export const proxyServiceFactory = ({
if (proxy.orgId) { if (proxy.orgId) {
const orgCAs = await $getOrgCAs(proxy.orgId); const orgCAs = await $getOrgCAs(proxy.orgId);
const instanceCAs = await $getInstanceCAs(); return $generateProxyServerCredentials({
return $generateProxyCredentials({
ip, ip,
orgId: proxy.orgId, orgId: proxy.orgId,
rootProxyPkiCaCertificate: instanceCAs.rootProxyPkiCaCertificate,
proxyPkiServerCaCertificate: orgCAs.proxyPkiServerCaCertificate, proxyPkiServerCaCertificate: orgCAs.proxyPkiServerCaCertificate,
proxyPkiServerCaPrivateKey: orgCAs.proxyPkiServerCaPrivateKey, proxyPkiServerCaPrivateKey: orgCAs.proxyPkiServerCaPrivateKey,
proxyPkiServerCaCertificateChain: orgCAs.proxyPkiServerCaCertificateChain, proxyPkiClientCaCertificate: orgCAs.proxyPkiClientCaCertificate,
proxyPkiClientCaCertificateChain: orgCAs.proxyPkiClientCaCertificateChain,
proxySshServerCaPrivateKey: orgCAs.proxySshServerCaPrivateKey, proxySshServerCaPrivateKey: orgCAs.proxySshServerCaPrivateKey,
proxySshClientCaPublicKey: orgCAs.proxySshClientCaPublicKey proxySshClientCaPublicKey: orgCAs.proxySshClientCaPublicKey
}); });
@@ -875,6 +1008,7 @@ export const proxyServiceFactory = ({
return { return {
registerProxy, registerProxy,
getCredentialsForGateway getCredentialsForGateway,
getCredentialsForClient
}; };
}; };

View File

@@ -38,6 +38,9 @@ import { externalKmsServiceFactory } from "@app/ee/services/external-kms/externa
import { gatewayDALFactory } from "@app/ee/services/gateway/gateway-dal"; import { gatewayDALFactory } from "@app/ee/services/gateway/gateway-dal";
import { gatewayServiceFactory } from "@app/ee/services/gateway/gateway-service"; import { gatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
import { orgGatewayConfigDALFactory } from "@app/ee/services/gateway/org-gateway-config-dal"; import { orgGatewayConfigDALFactory } from "@app/ee/services/gateway/org-gateway-config-dal";
import { gatewayV2DalFactory } from "@app/ee/services/gateway-v2/gateway-v2-dal";
import { gatewayV2ServiceFactory } from "@app/ee/services/gateway-v2/gateway-v2-service";
import { orgGatewayConfigV2DalFactory } from "@app/ee/services/gateway-v2/org-gateway-config-v2-dal";
import { githubOrgSyncDALFactory } from "@app/ee/services/github-org-sync/github-org-sync-dal"; import { githubOrgSyncDALFactory } from "@app/ee/services/github-org-sync/github-org-sync-dal";
import { githubOrgSyncServiceFactory } from "@app/ee/services/github-org-sync/github-org-sync-service"; import { githubOrgSyncServiceFactory } from "@app/ee/services/github-org-sync/github-org-sync-service";
import { groupDALFactory } from "@app/ee/services/group/group-dal"; import { groupDALFactory } from "@app/ee/services/group/group-dal";
@@ -72,6 +75,7 @@ import { projectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/proje
import { projectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-service"; import { projectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-service";
import { instanceProxyConfigDalFactory } from "@app/ee/services/proxy/instance-proxy-config-dal"; import { instanceProxyConfigDalFactory } from "@app/ee/services/proxy/instance-proxy-config-dal";
import { orgProxyConfigDalFactory } from "@app/ee/services/proxy/org-proxy-config-dal"; import { orgProxyConfigDalFactory } from "@app/ee/services/proxy/org-proxy-config-dal";
import { proxyDalFactory } from "@app/ee/services/proxy/proxy-dal";
import { proxyServiceFactory } from "@app/ee/services/proxy/proxy-service"; import { proxyServiceFactory } from "@app/ee/services/proxy/proxy-service";
import { rateLimitDALFactory } from "@app/ee/services/rate-limit/rate-limit-dal"; import { rateLimitDALFactory } from "@app/ee/services/rate-limit/rate-limit-dal";
import { rateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-service"; import { rateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-service";
@@ -147,8 +151,6 @@ import { tokenServiceFactory } from "@app/services/auth-token/auth-token-service
import { certificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal"; import { certificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
import { certificateDALFactory } from "@app/services/certificate/certificate-dal"; import { certificateDALFactory } from "@app/services/certificate/certificate-dal";
import { certificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal"; import { certificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal";
import { gatewayV2ServiceFactory } from "@app/ee/services/gateway-v2/gateway-v2-service";
import { orgGatewayConfigV2DalFactory } from "@app/ee/services/gateway-v2/org-gateway-config-v2-dal";
import { certificateServiceFactory } from "@app/services/certificate/certificate-service"; import { certificateServiceFactory } from "@app/services/certificate/certificate-service";
import { certificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal"; import { certificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal";
import { certificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal"; import { certificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal";
@@ -319,7 +321,6 @@ import { registerV1Routes } from "./v1";
import { initializeOauthConfigSync } from "./v1/sso-router"; import { initializeOauthConfigSync } from "./v1/sso-router";
import { registerV2Routes } from "./v2"; import { registerV2Routes } from "./v2";
import { registerV3Routes } from "./v3"; import { registerV3Routes } from "./v3";
import { proxyDalFactory } from "@app/ee/services/proxy/proxy-dal";
const histogram = monitorEventLoopDelay({ resolution: 20 }); const histogram = monitorEventLoopDelay({ resolution: 20 });
histogram.enable(); histogram.enable();
@@ -948,6 +949,7 @@ export const registerRoutes = async (
const instanceProxyConfigDAL = instanceProxyConfigDalFactory(db); const instanceProxyConfigDAL = instanceProxyConfigDalFactory(db);
const orgProxyConfigDAL = orgProxyConfigDalFactory(db); const orgProxyConfigDAL = orgProxyConfigDalFactory(db);
const proxyDAL = proxyDalFactory(db); const proxyDAL = proxyDalFactory(db);
const gatewayV2DAL = gatewayV2DalFactory(db);
const orgGatewayConfigV2DAL = orgGatewayConfigV2DalFactory(db); const orgGatewayConfigV2DAL = orgGatewayConfigV2DalFactory(db);
@@ -1626,9 +1628,26 @@ export const registerRoutes = async (
identityAuthTemplateDAL identityAuthTemplateDAL
}); });
const dynamicSecretProviders = buildDynamicSecretProviders({ const proxyService = proxyServiceFactory({
gatewayService instanceProxyConfigDAL,
orgProxyConfigDAL,
proxyDAL,
kmsService
}); });
const gatewayV2Service = gatewayV2ServiceFactory({
kmsService,
proxyService,
orgGatewayConfigV2DAL,
gatewayV2DAL,
proxyDAL
});
const dynamicSecretProviders = buildDynamicSecretProviders({
gatewayService,
gatewayV2Service
});
const dynamicSecretQueueService = dynamicSecretLeaseQueueServiceFactory({ const dynamicSecretQueueService = dynamicSecretLeaseQueueServiceFactory({
queueService, queueService,
dynamicSecretLeaseDAL, dynamicSecretLeaseDAL,
@@ -1648,6 +1667,7 @@ export const registerRoutes = async (
licenseService, licenseService,
kmsService, kmsService,
gatewayDAL, gatewayDAL,
gatewayV2DAL,
resourceMetadataDAL resourceMetadataDAL
}); });
@@ -1972,19 +1992,6 @@ export const registerRoutes = async (
appConnectionDAL appConnectionDAL
}); });
const proxyService = proxyServiceFactory({
instanceProxyConfigDAL,
orgProxyConfigDAL,
proxyDAL,
kmsService
});
const gatewayV2Service = gatewayV2ServiceFactory({
kmsService,
proxyService,
orgGatewayConfigV2DAL
});
// setup the communication with license key server // setup the communication with license key server
await licenseService.init(); await licenseService.init();

View File

@@ -0,0 +1 @@
export { gatewaysV2QueryKeys } from "./queries";

View File

@@ -0,0 +1,18 @@
import { queryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { TGatewayV2 } from "./types";
export const gatewaysV2QueryKeys = {
allKey: () => ["gateways-v2"],
listKey: () => [...gatewaysV2QueryKeys.allKey(), "list"],
list: () =>
queryOptions({
queryKey: gatewaysV2QueryKeys.listKey(),
queryFn: async () => {
const { data } = await apiRequest.get<{ gateways: TGatewayV2[] }>("/api/v2/gateways");
return data.gateways;
}
})
};

View File

@@ -0,0 +1,11 @@
export type TGatewayV2 = {
id: string;
identityId: string;
name: string;
createdAt: string;
updatedAt: string;
identity: {
name: string;
id: string;
};
};

View File

@@ -2,6 +2,7 @@ import { queryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request"; import { apiRequest } from "@app/config/request";
import { TGatewayV2 } from "../gateways-v2/types";
import { TGateway } from "./types"; import { TGateway } from "./types";
export const gatewaysQueryKeys = { export const gatewaysQueryKeys = {
@@ -12,7 +13,9 @@ export const gatewaysQueryKeys = {
queryKey: gatewaysQueryKeys.listKey(), queryKey: gatewaysQueryKeys.listKey(),
queryFn: async () => { queryFn: async () => {
const { data } = await apiRequest.get<{ gateways: TGateway[] }>("/api/v1/gateways"); const { data } = await apiRequest.get<{ gateways: TGateway[] }>("/api/v1/gateways");
return data.gateways; const { data: dataV2 } = await apiRequest.get<TGatewayV2[]>("/api/v2/gateways");
return [...data.gateways, ...dataV2];
} }
}) })
}; };