Merge branch 'main' into PAM-10

This commit is contained in:
x032205
2025-11-17 10:30:33 -05:00
132 changed files with 3035 additions and 963 deletions

View File

@@ -98,7 +98,6 @@
"ms": "^2.1.3",
"mysql2": "^3.9.8",
"nanoid": "^3.3.8",
"nock": "^14.0.10",
"node-forge": "^1.3.1",
"nodemailer": "^6.9.9",
"oci-sdk": "^2.108.0",
@@ -178,6 +177,7 @@
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-simple-import-sort": "^10.0.0",
"nock": "^14.0.10",
"nodemon": "^3.0.2",
"pino-pretty": "^10.2.3",
"prompt-sync": "^4.2.0",
@@ -9710,6 +9710,7 @@
"version": "0.39.8",
"resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.39.8.tgz",
"integrity": "sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@open-draft/deferred-promise": "^2.2.0",
@@ -10736,12 +10737,14 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz",
"integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==",
"dev": true,
"license": "MIT"
},
"node_modules/@open-draft/logger": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz",
"integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-node-process": "^1.2.0",
@@ -10752,6 +10755,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz",
"integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==",
"dev": true,
"license": "MIT"
},
"node_modules/@opentelemetry/api": {
@@ -23002,6 +23006,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
"integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==",
"dev": true,
"license": "MIT"
},
"node_modules/is-number": {
@@ -23557,6 +23562,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"dev": true,
"license": "ISC"
},
"node_modules/json5": {
@@ -25130,6 +25136,7 @@
"version": "14.0.10",
"resolved": "https://registry.npmjs.org/nock/-/nock-14.0.10.tgz",
"integrity": "sha512-Q7HjkpyPeLa0ZVZC5qpxBt5EyLczFJ91MEewQiIi9taWuA0KB/MDJlUWtON+7dGouVdADTQsf9RA7TZk6D8VMw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@mswjs/interceptors": "^0.39.5",
@@ -27772,6 +27779,7 @@
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz",
"integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==",
"dev": true,
"license": "MIT"
},
"node_modules/p-finally": {
@@ -29179,6 +29187,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
@@ -31686,6 +31695,7 @@
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
"integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==",
"dev": true,
"license": "MIT"
},
"node_modules/string_decoder": {

View File

@@ -123,6 +123,7 @@
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-simple-import-sort": "^10.0.0",
"nock": "^14.0.10",
"nodemon": "^3.0.2",
"pino-pretty": "^10.2.3",
"prompt-sync": "^4.2.0",
@@ -226,7 +227,6 @@
"ms": "^2.1.3",
"mysql2": "^3.9.8",
"nanoid": "^3.3.8",
"nock": "^14.0.10",
"node-forge": "^1.3.1",
"nodemailer": "^6.9.9",
"oci-sdk": "^2.108.0",

View File

@@ -435,14 +435,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
projectId: z.string().trim(),
environment: z.string().trim(),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
message: z
.string()
.trim()
.min(1)
.max(255)
.refine((message) => message.trim() !== "", {
message: "Commit message cannot be empty"
}),
message: z.string().trim().max(255).optional(),
changes: z.object({
secrets: z.object({
create: z
@@ -546,7 +539,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
projectId: req.body.projectId,
environment: req.body.environment,
secretPath: req.body.secretPath,
message: req.body.message,
message: req.body.message || "",
changes: {
secrets: req.body.changes.secrets,
folders: req.body.changes.folders
@@ -564,7 +557,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
projectId: req.body.projectId,
environment: req.body.environment,
secretPath: req.body.secretPath,
message: req.body.message
message: req.body.message || ""
}
}
});

View File

@@ -2,6 +2,7 @@ import z from "zod";
import { AppConnections } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "@app/services/app-connection/app-connection-maps";
import {
BaseAppConnectionSchema,
GenericCreateAppConnectionFieldsSchema,
@@ -48,7 +49,7 @@ export const SanitizedChefConnectionSchema = z.discriminatedUnion("method", [
BaseChefConnectionSchema.extend({
method: z.literal(ChefConnectionMethod.UserKey),
credentials: ChefConnectionUserKeyCredentialsSchema.pick({ serverUrl: true, orgName: true, userName: true })
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Chef]} (User Key)` }))
]);
export const ValidateChefConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -70,8 +71,10 @@ export const UpdateChefConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Chef));
export const ChefConnectionListItemSchema = z.object({
name: z.literal("Chef"),
app: z.literal(AppConnection.Chef),
methods: z.nativeEnum(ChefConnectionMethod).array()
});
export const ChefConnectionListItemSchema = z
.object({
name: z.literal("Chef"),
app: z.literal(AppConnection.Chef),
methods: z.nativeEnum(ChefConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Chef] }));

View File

@@ -2,6 +2,7 @@ import z from "zod";
import { AppConnections } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "@app/services/app-connection/app-connection-maps";
import {
BaseAppConnectionSchema,
GenericCreateAppConnectionFieldsSchema,
@@ -34,7 +35,7 @@ export const SanitizedOCIConnectionSchema = z.discriminatedUnion("method", [
region: true,
fingerprint: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.OCI]} (Access Key)` }))
]);
export const ValidateOCIConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -58,8 +59,10 @@ export const UpdateOCIConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OCI));
export const OCIConnectionListItemSchema = z.object({
name: z.literal("OCI"),
app: z.literal(AppConnection.OCI),
methods: z.nativeEnum(OCIConnectionMethod).array()
});
export const OCIConnectionListItemSchema = z
.object({
name: z.literal("OCI"),
app: z.literal(AppConnection.OCI),
methods: z.nativeEnum(OCIConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.OCI] }));

View File

@@ -2,6 +2,7 @@ import z from "zod";
import { AppConnections } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "@app/services/app-connection/app-connection-maps";
import {
BaseAppConnectionSchema,
GenericCreateAppConnectionFieldsSchema,
@@ -32,7 +33,7 @@ export const SanitizedOracleDBConnectionSchema = z.discriminatedUnion("method",
sslRejectUnauthorized: true,
sslCertificate: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.OracleDB]} (Username and Password)` }))
]);
export const ValidateOracleDBConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -64,9 +65,11 @@ export const UpdateOracleDBConnectionSchema = z
})
);
export const OracleDBConnectionListItemSchema = z.object({
name: z.literal("OracleDB"),
app: z.literal(AppConnection.OracleDB),
methods: z.nativeEnum(OracleDBConnectionMethod).array(),
supportsPlatformManagement: z.literal(true)
});
export const OracleDBConnectionListItemSchema = z
.object({
name: z.literal("OracleDB"),
app: z.literal(AppConnection.OracleDB),
methods: z.nativeEnum(OracleDBConnectionMethod).array(),
supportsPlatformManagement: z.literal(true)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.OracleDB] }));

View File

@@ -365,6 +365,8 @@ export enum EventType {
LOAD_PROJECT_KMS_BACKUP = "load-project-kms-backup",
ORG_ADMIN_ACCESS_PROJECT = "org-admin-accessed-project",
ORG_ADMIN_BYPASS_SSO = "org-admin-bypassed-sso",
USER_LOGIN = "user-login",
SELECT_ORGANIZATION = "select-organization",
CREATE_CERTIFICATE_TEMPLATE = "create-certificate-template",
UPDATE_CERTIFICATE_TEMPLATE = "update-certificate-template",
DELETE_CERTIFICATE_TEMPLATE = "delete-certificate-template",
@@ -570,6 +572,7 @@ interface UserActorMetadata {
email?: string | null;
username: string;
permission?: Record<string, unknown>;
authMethod?: string;
}
interface ServiceActorMetadata {
@@ -2657,6 +2660,22 @@ interface OrgAdminBypassSSOEvent {
metadata: Record<string, string>; // no metadata yet
}
interface UserLoginEvent {
type: EventType.USER_LOGIN;
metadata: {
organizationId?: string;
authProvider?: string;
};
}
interface SelectOrganizationEvent {
type: EventType.SELECT_ORGANIZATION;
metadata: {
organizationId: string;
organizationName: string;
};
}
interface CreateCertificateTemplateEstConfig {
type: EventType.CREATE_CERTIFICATE_TEMPLATE_EST_CONFIG;
metadata: {
@@ -4535,4 +4554,6 @@ export type Event =
| UpdateCertificateRenewalConfigEvent
| DisableCertificateRenewalConfigEvent
| AutomatedRenewCertificate
| AutomatedRenewCertificateFailed;
| AutomatedRenewCertificateFailed
| UserLoginEvent
| SelectOrganizationEvent;

View File

@@ -10,7 +10,7 @@ import {
import { logger } from "@app/lib/logger";
import { DistinguishedNameRegex } from "@app/lib/regex";
import { encryptAppConnectionCredentials } from "@app/services/app-connection/app-connection-fns";
import { getLdapConnectionClient, LdapProvider, TLdapConnection } from "@app/services/app-connection/ldap";
import { executeWithPotentialGateway, LdapProvider, TLdapConnection } from "@app/services/app-connection/ldap";
import { generatePassword } from "../shared/utils";
import {
@@ -71,17 +71,18 @@ export const ldapPasswordRotationFactory: TRotationFactory<
TLdapPasswordRotationWithConnection,
TLdapPasswordRotationGeneratedCredentials,
TLdapPasswordRotationInput["temporaryParameters"]
> = (secretRotation, appConnectionDAL, kmsService) => {
> = (secretRotation, appConnectionDAL, kmsService, gatewayService, gatewayV2Service) => {
const { connection, parameters, secretsMapping, activeIndex } = secretRotation;
const { dn, passwordRequirements } = parameters;
const $verifyCredentials = async (credentials: Pick<TLdapConnection["credentials"], "dn" | "password">) => {
try {
const client = await getLdapConnectionClient({ ...connection.credentials, ...credentials });
client.unbind();
client.destroy();
await executeWithPotentialGateway(
{ ...connection, credentials: { ...connection.credentials, ...credentials } },
gatewayV2Service,
async () => {}
);
} catch (error) {
throw new Error(`Failed to verify credentials - ${(error as Error).message}`);
}
@@ -92,17 +93,7 @@ export const ldapPasswordRotationFactory: TRotationFactory<
if (!credentials.url.startsWith("ldaps")) throw new Error("Password Rotation requires an LDAPS connection");
const client = await getLdapConnectionClient(
currentPassword
? {
...credentials,
password: currentPassword,
dn
}
: credentials
);
const isConnectionRotation = credentials.dn === dn;
const password = generatePassword(passwordRequirements);
let changes: ldap.Change[] | ldap.Change;
@@ -147,22 +138,32 @@ export const ldapPasswordRotationFactory: TRotationFactory<
throw new Error(`Unhandled provider: ${credentials.provider as LdapProvider}`);
}
try {
const userDn = await getDN(dn, client);
await new Promise((resolve, reject) => {
client.modify(userDn, changes, (err) => {
if (err) {
logger.error(err, "LDAP Password Rotation Failed");
reject(new Error(`Provider Modify Error: ${err.message}`));
} else {
resolve(true);
}
await executeWithPotentialGateway(
{
...connection,
credentials: currentPassword
? {
...credentials,
password: currentPassword,
dn
}
: credentials
},
gatewayV2Service,
async (client) => {
const userDn = await getDN(dn, client);
await new Promise<void>((resolve, reject) => {
client.modify(userDn, changes, (err) => {
if (err) {
logger.error(err, "LDAP Password Rotation Failed");
reject(new Error(`Provider Modify Error: ${err.message}`));
} else {
resolve();
}
});
});
});
} finally {
client.unbind();
client.destroy();
}
}
);
await $verifyCredentials({ dn, password });

View File

@@ -3,6 +3,7 @@ import { z } from "zod";
import { SecretSyncs } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { SecretSync } from "@app/services/secret-sync/secret-sync-enums";
import { SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps";
import {
BaseSecretSyncSchema,
GenericCreateSecretSyncFieldsSchema,
@@ -25,10 +26,12 @@ const ChefSyncDestinationConfigSchema = z.object({
const ChefSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const ChefSyncSchema = BaseSecretSyncSchema(SecretSync.Chef, ChefSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Chef),
destinationConfig: ChefSyncDestinationConfigSchema
});
export const ChefSyncSchema = BaseSecretSyncSchema(SecretSync.Chef, ChefSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Chef),
destinationConfig: ChefSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Chef] }));
export const CreateChefSyncSchema = GenericCreateSecretSyncFieldsSchema(SecretSync.Chef, ChefSyncOptionsConfig).extend({
destinationConfig: ChefSyncDestinationConfigSchema
@@ -38,10 +41,12 @@ export const UpdateChefSyncSchema = GenericUpdateSecretSyncFieldsSchema(SecretSy
destinationConfig: ChefSyncDestinationConfigSchema.optional()
});
export const ChefSyncListItemSchema = z.object({
name: z.literal("Chef"),
connection: z.literal(AppConnection.Chef),
destination: z.literal(SecretSync.Chef),
canImportSecrets: z.literal(true),
enterprise: z.boolean()
});
export const ChefSyncListItemSchema = z
.object({
name: z.literal("Chef"),
connection: z.literal(AppConnection.Chef),
destination: z.literal(SecretSync.Chef),
canImportSecrets: z.literal(true),
enterprise: z.boolean()
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Chef] }));

View File

@@ -4,6 +4,7 @@ import { z } from "zod";
import { SecretSyncs } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { SecretSync } from "@app/services/secret-sync/secret-sync-enums";
import { SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps";
import {
BaseSecretSyncSchema,
GenericCreateSecretSyncFieldsSchema,
@@ -43,10 +44,12 @@ const OCIVaultSyncDestinationConfigSchema = z.object({
const OCIVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const OCIVaultSyncSchema = BaseSecretSyncSchema(SecretSync.OCIVault, OCIVaultSyncOptionsConfig).extend({
destination: z.literal(SecretSync.OCIVault),
destinationConfig: OCIVaultSyncDestinationConfigSchema
});
export const OCIVaultSyncSchema = BaseSecretSyncSchema(SecretSync.OCIVault, OCIVaultSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.OCIVault),
destinationConfig: OCIVaultSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OCIVault] }));
export const CreateOCIVaultSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.OCIVault,
@@ -62,10 +65,12 @@ export const UpdateOCIVaultSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: OCIVaultSyncDestinationConfigSchema.optional()
});
export const OCIVaultSyncListItemSchema = z.object({
name: z.literal("OCI Vault"),
connection: z.literal(AppConnection.OCI),
destination: z.literal(SecretSync.OCIVault),
canImportSecrets: z.literal(true),
enterprise: z.boolean()
});
export const OCIVaultSyncListItemSchema = z
.object({
name: z.literal("OCI Vault"),
connection: z.literal(AppConnection.OCI),
destination: z.literal(SecretSync.OCIVault),
canImportSecrets: z.literal(true),
enterprise: z.boolean()
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OCIVault] }));

View File

@@ -8,10 +8,10 @@ import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "../errors";
import { isPrivateIp } from "../ip/ipRange";
export const blockLocalAndPrivateIpAddresses = async (url: string) => {
export const blockLocalAndPrivateIpAddresses = async (url: string, isGateway = false) => {
const appCfg = getConfig();
if (appCfg.isDevelopmentMode) return;
if (appCfg.isDevelopmentMode || isGateway) return;
const validUrl = new URL(url);

View File

@@ -643,7 +643,8 @@ export const registerRoutes = async (
projectDAL,
identityDAL,
userDAL,
externalGroupOrgRoleMappingDAL
externalGroupOrgRoleMappingDAL,
membershipRoleDAL
});
const additionalPrivilegeService = additionalPrivilegeServiceFactory({
additionalPrivilegeDAL,

View File

@@ -1,88 +1,87 @@
import nock, { Definition } from "nock";
import { z } from "zod";
// import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
import { ForbiddenRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
// import { getConfig } from "@app/lib/config/env";
// import { ForbiddenRequestError } from "@app/lib/errors";
// import { logger } from "@app/lib/logger";
// import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
// import { AuthMode } from "@app/services/auth/auth-type";
export const registerBddNockRouter = async (server: FastifyZodProvider) => {
const checkIfBddNockApiEnabled = () => {
const appCfg = getConfig();
// Note: Please note that this API is only available in development mode and only for BDD tests.
// This endpoint should NEVER BE ENABLED IN PRODUCTION!
if (appCfg.NODE_ENV !== "development" || !appCfg.isBddNockApiEnabled) {
throw new ForbiddenRequestError({ message: "BDD Nock API is not enabled" });
}
};
// export const registerBddNockRouter = async (server: FastifyZodProvider) => {
// const checkIfBddNockApiEnabled = () => {
// const appCfg = getConfig();
// // Note: Please note that this API is only available in development mode and only for BDD tests.
// // This endpoint should NEVER BE ENABLED IN PRODUCTION!
// if (appCfg.NODE_ENV !== "development" || !appCfg.isBddNockApiEnabled) {
// throw new ForbiddenRequestError({ message: "BDD Nock API is not enabled" });
// }
// };
server.route({
method: "POST",
url: "/define",
schema: {
body: z.object({ definitions: z.unknown().array() }),
response: {
200: z.object({ status: z.string() })
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
checkIfBddNockApiEnabled();
const { body } = req;
const { definitions } = body;
logger.info(definitions, "Defining nock");
const processedDefinitions = definitions.map((definition: unknown) => {
const { path, ...rest } = definition as Definition;
return {
...rest,
path:
path !== undefined && typeof path === "string"
? path
: new RegExp((path as unknown as { regex: string }).regex ?? "")
} as Definition;
});
// server.route({
// method: "POST",
// url: "/define",
// schema: {
// body: z.object({ definitions: z.unknown().array() }),
// response: {
// 200: z.object({ status: z.string() })
// }
// },
// onRequest: verifyAuth([AuthMode.JWT]),
// handler: async (req) => {
// checkIfBddNockApiEnabled();
// const { body } = req;
// const { definitions } = body;
// logger.info(definitions, "Defining nock");
// const processedDefinitions = definitions.map((definition: unknown) => {
// const { path, ...rest } = definition as Definition;
// return {
// ...rest,
// path:
// path !== undefined && typeof path === "string"
// ? path
// : new RegExp((path as unknown as { regex: string }).regex ?? "")
// } as Definition;
// });
nock.define(processedDefinitions);
// Ensure we are activating the nocks, because we could have called `nock.restore()` before this call.
if (!nock.isActive()) {
nock.activate();
}
return { status: "ok" };
}
});
// nock.define(processedDefinitions);
// // Ensure we are activating the nocks, because we could have called `nock.restore()` before this call.
// if (!nock.isActive()) {
// nock.activate();
// }
// return { status: "ok" };
// }
// });
server.route({
method: "POST",
url: "/clean-all",
schema: {
response: {
200: z.object({ status: z.string() })
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async () => {
checkIfBddNockApiEnabled();
logger.info("Cleaning all nocks");
nock.cleanAll();
return { status: "ok" };
}
});
// server.route({
// method: "POST",
// url: "/clean-all",
// schema: {
// response: {
// 200: z.object({ status: z.string() })
// }
// },
// onRequest: verifyAuth([AuthMode.JWT]),
// handler: async () => {
// checkIfBddNockApiEnabled();
// logger.info("Cleaning all nocks");
// nock.cleanAll();
// return { status: "ok" };
// }
// });
server.route({
method: "POST",
url: "/restore",
schema: {
response: {
200: z.object({ status: z.string() })
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async () => {
checkIfBddNockApiEnabled();
logger.info("Restore network requests from nock");
nock.restore();
return { status: "ok" };
}
});
};
// server.route({
// method: "POST",
// url: "/restore",
// schema: {
// response: {
// 200: z.object({ status: z.string() })
// }
// },
// onRequest: verifyAuth([AuthMode.JWT]),
// handler: async () => {
// checkIfBddNockApiEnabled();
// logger.info("Restore network requests from nock");
// nock.restore();
// return { status: "ok" };
// }
// });
// };

View File

@@ -9,7 +9,7 @@ import { registerSecretSyncRouter, SECRET_SYNC_REGISTER_ROUTER_MAP } from "@app/
import { registerAdminRouter } from "./admin-router";
import { registerAuthRoutes } from "./auth-router";
import { registerBddNockRouter } from "./bdd-nock-router";
// import { registerBddNockRouter } from "./bdd-nock-router";
import { registerProjectBotRouter } from "./bot-router";
import { registerCaRouter } from "./certificate-authority-router";
import { CERTIFICATE_AUTHORITY_REGISTER_ROUTER_MAP } from "./certificate-authority-routers";
@@ -242,7 +242,7 @@ export const registerV1Routes = async (server: FastifyZodProvider) => {
// Note: This is a special route for BDD tests. It's only available in development mode and only for BDD tests.
// This route should NEVER BE ENABLED IN PRODUCTION!
if (getConfig().isBddNockApiEnabled) {
await server.register(registerBddNockRouter, { prefix: "/bdd-nock" });
}
// if (getConfig().isBddNockApiEnabled) {
// await server.register(registerBddNockRouter, { prefix: "/bdd-nock" });
// }
};

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { OnePassConnectionMethod } from "./1password-connection-enums";
export const OnePassConnectionAccessTokenCredentialsSchema = z.object({
@@ -33,7 +34,7 @@ export const SanitizedOnePassConnectionSchema = z.discriminatedUnion("method", [
credentials: OnePassConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.OnePass]} (API Token)` }))
]);
export const ValidateOnePassConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -57,8 +58,10 @@ export const UpdateOnePassConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OnePass));
export const OnePassConnectionListItemSchema = z.object({
name: z.literal("1Password"),
app: z.literal(AppConnection.OnePass),
methods: z.nativeEnum(OnePassConnectionMethod).array()
});
export const OnePassConnectionListItemSchema = z
.object({
name: z.literal("1Password"),
app: z.literal(AppConnection.OnePass),
methods: z.nativeEnum(OnePassConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.OnePass] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { Auth0ConnectionMethod } from "./auth0-connection-enums";
export const Auth0ConnectionClientCredentialsInputCredentialsSchema = z.object({
@@ -59,7 +60,7 @@ export const SanitizedAuth0ConnectionSchema = z.discriminatedUnion("method", [
clientId: true,
audience: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Auth0]} (Client Credentials)` }))
]);
export const ValidateAuth0ConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -85,10 +86,12 @@ export const UpdateAuth0ConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Auth0));
export const Auth0ConnectionListItemSchema = z.object({
name: z.literal("Auth0"),
app: z.literal(AppConnection.Auth0),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]),
methods: z.nativeEnum(Auth0ConnectionMethod).array()
});
export const Auth0ConnectionListItemSchema = z
.object({
name: z.literal("Auth0"),
app: z.literal(AppConnection.Auth0),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]),
methods: z.nativeEnum(Auth0ConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Auth0] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AwsConnectionMethod } from "./aws-connection-enums";
export const AwsConnectionAssumeRoleCredentialsSchema = z.object({
@@ -39,11 +40,11 @@ export const SanitizedAwsConnectionSchema = z.discriminatedUnion("method", [
BaseAwsConnectionSchema.extend({
method: z.literal(AwsConnectionMethod.AssumeRole),
credentials: AwsConnectionAssumeRoleCredentialsSchema.pick({})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AWS]} (Assume Role)` })),
BaseAwsConnectionSchema.extend({
method: z.literal(AwsConnectionMethod.AccessKey),
credentials: AwsConnectionAccessTokenCredentialsSchema.pick({ accessKeyId: true })
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AWS]} (Access Key)` }))
]);
export const ValidateAwsConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -72,11 +73,13 @@ export const UpdateAwsConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.AWS));
export const AwsConnectionListItemSchema = z.object({
name: z.literal("AWS"),
app: z.literal(AppConnection.AWS),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(AwsConnectionMethod.AssumeRole), z.literal(AwsConnectionMethod.AccessKey)]),
methods: z.nativeEnum(AwsConnectionMethod).array(),
accessKeyId: z.string().optional()
});
export const AwsConnectionListItemSchema = z
.object({
name: z.literal("AWS"),
app: z.literal(AppConnection.AWS),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(AwsConnectionMethod.AssumeRole), z.literal(AwsConnectionMethod.AccessKey)]),
methods: z.nativeEnum(AwsConnectionMethod).array(),
accessKeyId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AWS] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AzureADCSConnectionMethod } from "./azure-adcs-connection-enums";
export const AzureADCSUsernamePasswordCredentialsSchema = z.object({
@@ -55,7 +56,7 @@ export const SanitizedAzureADCSConnectionSchema = z.discriminatedUnion("method",
sslRejectUnauthorized: true,
sslCertificate: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureADCS]} (Username and Password)` }))
]);
export const ValidateAzureADCSConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -81,8 +82,10 @@ export const UpdateAzureADCSConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.AzureADCS));
export const AzureADCSConnectionListItemSchema = z.object({
name: z.literal("Azure ADCS"),
app: z.literal(AppConnection.AzureADCS),
methods: z.nativeEnum(AzureADCSConnectionMethod).array()
});
export const AzureADCSConnectionListItemSchema = z
.object({
name: z.literal("Azure ADCS"),
app: z.literal(AppConnection.AzureADCS),
methods: z.nativeEnum(AzureADCSConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureADCS] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AzureAppConfigurationConnectionMethod } from "./azure-app-configuration-connection-enums";
export const AzureAppConfigurationConnectionOAuthInputCredentialsSchema = z.object({
@@ -104,19 +105,23 @@ export const SanitizedAzureAppConfigurationConnectionSchema = z.discriminatedUni
credentials: AzureAppConfigurationConnectionOAuthOutputCredentialsSchema.pick({
tenantId: true
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureAppConfiguration]} (OAuth)` })),
BaseAzureAppConfigurationConnectionSchema.extend({
method: z.literal(AzureAppConfigurationConnectionMethod.ClientSecret),
credentials: AzureAppConfigurationConnectionClientSecretOutputCredentialsSchema.pick({
clientId: true,
tenantId: true
})
})
}).describe(
JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureAppConfiguration]} (Client Secret)` })
)
]);
export const AzureAppConfigurationConnectionListItemSchema = z.object({
name: z.literal("Azure App Configuration"),
app: z.literal(AppConnection.AzureAppConfiguration),
methods: z.nativeEnum(AzureAppConfigurationConnectionMethod).array(),
oauthClientId: z.string().optional()
});
export const AzureAppConfigurationConnectionListItemSchema = z
.object({
name: z.literal("Azure App Configuration"),
app: z.literal(AppConnection.AzureAppConfiguration),
methods: z.nativeEnum(AzureAppConfigurationConnectionMethod).array(),
oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureAppConfiguration] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AzureClientSecretsConnectionMethod } from "./azure-client-secrets-connection-enums";
export const AzureClientSecretsConnectionOAuthInputCredentialsSchema = z.object({
@@ -162,26 +163,30 @@ export const SanitizedAzureClientSecretsConnectionSchema = z.discriminatedUnion(
credentials: AzureClientSecretsConnectionOAuthOutputCredentialsSchema.pick({
tenantId: true
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureClientSecrets]} (OAuth)` })),
BaseAzureClientSecretsConnectionSchema.extend({
method: z.literal(AzureClientSecretsConnectionMethod.ClientSecret),
credentials: AzureClientSecretsConnectionClientSecretOutputCredentialsSchema.pick({
clientId: true,
tenantId: true
})
}),
}).describe(
JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureClientSecrets]} (Client Secret)` })
),
BaseAzureClientSecretsConnectionSchema.extend({
method: z.literal(AzureClientSecretsConnectionMethod.Certificate),
credentials: AzureClientSecretsConnectionCertificateOutputCredentialsSchema.pick({
tenantId: true,
clientId: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureClientSecrets]} (Certificate)` }))
]);
export const AzureClientSecretsConnectionListItemSchema = z.object({
name: z.literal("Azure Client Secrets"),
app: z.literal(AppConnection.AzureClientSecrets),
methods: z.nativeEnum(AzureClientSecretsConnectionMethod).array(),
oauthClientId: z.string().optional()
});
export const AzureClientSecretsConnectionListItemSchema = z
.object({
name: z.literal("Azure Client Secrets"),
app: z.literal(AppConnection.AzureClientSecrets),
methods: z.nativeEnum(AzureClientSecretsConnectionMethod).array(),
oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureClientSecrets] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AzureDevOpsConnectionMethod } from "./azure-devops-enums";
export const AzureDevOpsConnectionOAuthInputCredentialsSchema = z.object({
@@ -147,13 +148,13 @@ export const SanitizedAzureDevOpsConnectionSchema = z.discriminatedUnion("method
tenantId: true,
orgName: true
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureDevOps]} (OAuth)` })),
BaseAzureDevOpsConnectionSchema.extend({
method: z.literal(AzureDevOpsConnectionMethod.AccessToken),
credentials: AzureDevOpsConnectionAccessTokenOutputCredentialsSchema.pick({
orgName: true
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureDevOps]} (Access Token)` })),
BaseAzureDevOpsConnectionSchema.extend({
method: z.literal(AzureDevOpsConnectionMethod.ClientSecret),
credentials: AzureDevOpsConnectionClientSecretOutputCredentialsSchema.pick({
@@ -161,12 +162,14 @@ export const SanitizedAzureDevOpsConnectionSchema = z.discriminatedUnion("method
tenantId: true,
orgName: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureDevOps]} (Client Secret)` }))
]);
export const AzureDevOpsConnectionListItemSchema = z.object({
name: z.literal("Azure DevOps"),
app: z.literal(AppConnection.AzureDevOps),
methods: z.nativeEnum(AzureDevOpsConnectionMethod).array(),
oauthClientId: z.string().optional()
});
export const AzureDevOpsConnectionListItemSchema = z
.object({
name: z.literal("Azure DevOps"),
app: z.literal(AppConnection.AzureDevOps),
methods: z.nativeEnum(AzureDevOpsConnectionMethod).array(),
oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureDevOps] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AzureKeyVaultConnectionMethod } from "./azure-key-vault-connection-enums";
export const AzureKeyVaultConnectionOAuthInputCredentialsSchema = z.object({
@@ -104,19 +105,21 @@ export const SanitizedAzureKeyVaultConnectionSchema = z.discriminatedUnion("meth
credentials: AzureKeyVaultConnectionOAuthOutputCredentialsSchema.pick({
tenantId: true
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureKeyVault]} (OAuth)` })),
BaseAzureKeyVaultConnectionSchema.extend({
method: z.literal(AzureKeyVaultConnectionMethod.ClientSecret),
credentials: AzureKeyVaultConnectionClientSecretOutputCredentialsSchema.pick({
clientId: true,
tenantId: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureKeyVault]} (Client Secret)` }))
]);
export const AzureKeyVaultConnectionListItemSchema = z.object({
name: z.literal("Azure Key Vault"),
app: z.literal(AppConnection.AzureKeyVault),
methods: z.nativeEnum(AzureKeyVaultConnectionMethod).array(),
oauthClientId: z.string().optional()
});
export const AzureKeyVaultConnectionListItemSchema = z
.object({
name: z.literal("Azure Key Vault"),
app: z.literal(AppConnection.AzureKeyVault),
methods: z.nativeEnum(AzureKeyVaultConnectionMethod).array(),
oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureKeyVault] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { BitbucketConnectionMethod } from "./bitbucket-connection-enums";
export const BitbucketConnectionAccessTokenCredentialsSchema = z.object({
@@ -39,7 +40,7 @@ export const SanitizedBitbucketConnectionSchema = z.discriminatedUnion("method",
credentials: BitbucketConnectionAccessTokenCredentialsSchema.pick({
email: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Bitbucket]} (API Token)` }))
]);
export const ValidateBitbucketConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -65,8 +66,10 @@ export const UpdateBitbucketConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Bitbucket));
export const BitbucketConnectionListItemSchema = z.object({
name: z.literal("Bitbucket"),
app: z.literal(AppConnection.Bitbucket),
methods: z.nativeEnum(BitbucketConnectionMethod).array()
});
export const BitbucketConnectionListItemSchema = z
.object({
name: z.literal("Bitbucket"),
app: z.literal(AppConnection.Bitbucket),
methods: z.nativeEnum(BitbucketConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Bitbucket] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { CamundaConnectionMethod } from "./camunda-connection-enums";
const BaseCamundaConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.Camunda) });
@@ -44,7 +45,7 @@ export const SanitizedCamundaConnectionSchema = z.discriminatedUnion("method", [
credentials: CamundaConnectionClientCredentialsOutputCredentialsSchema.pick({
clientId: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Camunda]} (Client Credentials)` }))
]);
export const ValidateCamundaConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -70,8 +71,10 @@ export const UpdateCamundaConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Camunda));
export const CamundaConnectionListItemSchema = z.object({
name: z.literal("Camunda"),
app: z.literal(AppConnection.Camunda),
methods: z.nativeEnum(CamundaConnectionMethod).array()
});
export const CamundaConnectionListItemSchema = z
.object({
name: z.literal("Camunda"),
app: z.literal(AppConnection.Camunda),
methods: z.nativeEnum(CamundaConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Camunda] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { ChecklyConnectionMethod } from "./checkly-connection-constants";
export const ChecklyConnectionMethodSchema = z
@@ -31,7 +32,7 @@ export const SanitizedChecklyConnectionSchema = z.discriminatedUnion("method", [
BaseChecklyConnectionSchema.extend({
method: ChecklyConnectionMethodSchema,
credentials: ChecklyConnectionAccessTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Checkly]} (Access Token)` }))
]);
export const ValidateChecklyConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -55,8 +56,10 @@ export const UpdateChecklyConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Checkly));
export const ChecklyConnectionListItemSchema = z.object({
name: z.literal("Checkly"),
app: z.literal(AppConnection.Checkly),
methods: z.nativeEnum(ChecklyConnectionMethod).array()
});
export const ChecklyConnectionListItemSchema = z
.object({
name: z.literal("Checkly"),
app: z.literal(AppConnection.Checkly),
methods: z.nativeEnum(ChecklyConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Checkly] }));

View File

@@ -9,6 +9,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { CloudflareConnectionMethod } from "./cloudflare-connection-enum";
const accountIdCharacterValidator = characterValidator([
@@ -41,7 +42,7 @@ export const SanitizedCloudflareConnectionSchema = z.discriminatedUnion("method"
BaseCloudflareConnectionSchema.extend({
method: z.literal(CloudflareConnectionMethod.APIToken),
credentials: CloudflareConnectionApiTokenCredentialsSchema.pick({ accountId: true })
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Cloudflare]} (API Token)` }))
]);
export const ValidateCloudflareConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -67,8 +68,10 @@ export const UpdateCloudflareConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Cloudflare));
export const CloudflareConnectionListItemSchema = z.object({
name: z.literal("Cloudflare"),
app: z.literal(AppConnection.Cloudflare),
methods: z.nativeEnum(CloudflareConnectionMethod).array()
});
export const CloudflareConnectionListItemSchema = z
.object({
name: z.literal("Cloudflare"),
app: z.literal(AppConnection.Cloudflare),
methods: z.nativeEnum(CloudflareConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Cloudflare] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { DatabricksConnectionMethod } from "./databricks-connection-enums";
export const DatabricksConnectionServicePrincipalInputCredentialsSchema = z.object({
@@ -42,7 +43,7 @@ export const SanitizedDatabricksConnectionSchema = z.discriminatedUnion("method"
clientId: true,
workspaceUrl: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Databricks]} (Service Principal)` }))
]);
export const ValidateDatabricksConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -68,10 +69,12 @@ export const UpdateDatabricksConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Databricks));
export const DatabricksConnectionListItemSchema = z.object({
name: z.literal("Databricks"),
app: z.literal(AppConnection.Databricks),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]),
methods: z.nativeEnum(DatabricksConnectionMethod).array()
});
export const DatabricksConnectionListItemSchema = z
.object({
name: z.literal("Databricks"),
app: z.literal(AppConnection.Databricks),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]),
methods: z.nativeEnum(DatabricksConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Databricks] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { DigitalOceanConnectionMethod } from "./digital-ocean-connection-constants";
export const DigitalOceanConnectionMethodSchema = z
@@ -36,7 +37,7 @@ export const SanitizedDigitalOceanConnectionSchema = z.discriminatedUnion("metho
BaseDigitalOceanConnectionSchema.extend({
method: DigitalOceanConnectionMethodSchema,
credentials: DigitalOceanConnectionAccessTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.DigitalOcean]} (Access Token)` }))
]);
export const ValidateDigitalOceanConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -60,8 +61,10 @@ export const UpdateDigitalOceanConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.DigitalOcean));
export const DigitalOceanConnectionListItemSchema = z.object({
name: z.literal("Digital Ocean"),
app: z.literal(AppConnection.DigitalOcean),
methods: z.nativeEnum(DigitalOceanConnectionMethod).array()
});
export const DigitalOceanConnectionListItemSchema = z
.object({
name: z.literal("Digital Ocean"),
app: z.literal(AppConnection.DigitalOcean),
methods: z.nativeEnum(DigitalOceanConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.DigitalOcean] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { FlyioConnectionMethod } from "./flyio-connection-enums";
export const FlyioConnectionAccessTokenCredentialsSchema = z.object({
@@ -31,7 +32,7 @@ export const SanitizedFlyioConnectionSchema = z.discriminatedUnion("method", [
BaseFlyioConnectionSchema.extend({
method: z.literal(FlyioConnectionMethod.AccessToken),
credentials: FlyioConnectionAccessTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Flyio]} (Access Token)` }))
]);
export const ValidateFlyioConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -55,8 +56,10 @@ export const UpdateFlyioConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Flyio));
export const FlyioConnectionListItemSchema = z.object({
name: z.literal("Fly.io"),
app: z.literal(AppConnection.Flyio),
methods: z.nativeEnum(FlyioConnectionMethod).array()
});
export const FlyioConnectionListItemSchema = z
.object({
name: z.literal("Fly.io"),
app: z.literal(AppConnection.Flyio),
methods: z.nativeEnum(FlyioConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Flyio] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { GcpConnectionMethod } from "./gcp-connection-enums";
export const GcpConnectionServiceAccountImpersonationCredentialsSchema = z.object({
@@ -30,7 +31,9 @@ export const SanitizedGcpConnectionSchema = z.discriminatedUnion("method", [
BaseGcpConnectionSchema.extend({
method: z.literal(GcpConnectionMethod.ServiceAccountImpersonation),
credentials: GcpConnectionServiceAccountImpersonationCredentialsSchema.pick({})
})
}).describe(
JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GCP]} (Service Account Impersonation)` })
)
]);
export const ValidateGcpConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -56,10 +59,12 @@ export const UpdateGcpConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.GCP));
export const GcpConnectionListItemSchema = z.object({
name: z.literal("GCP"),
app: z.literal(AppConnection.GCP),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]),
methods: z.nativeEnum(GcpConnectionMethod).array()
});
export const GcpConnectionListItemSchema = z
.object({
name: z.literal("GCP"),
app: z.literal(AppConnection.GCP),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]),
methods: z.nativeEnum(GcpConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.GCP] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { GitHubRadarConnectionMethod } from "./github-radar-connection-enums";
export const GitHubRadarConnectionInputCredentialsSchema = z.object({
@@ -53,14 +54,16 @@ export const SanitizedGitHubRadarConnectionSchema = z.discriminatedUnion("method
BaseGitHubRadarConnectionSchema.extend({
method: z.literal(GitHubRadarConnectionMethod.App),
credentials: GitHubRadarConnectionOutputCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitHubRadar]} (GitHub App)` }))
]);
export const GitHubRadarConnectionListItemSchema = z.object({
name: z.literal("GitHub Radar"),
app: z.literal(AppConnection.GitHubRadar),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]),
methods: z.nativeEnum(GitHubRadarConnectionMethod).array(),
appClientSlug: z.string().optional()
});
export const GitHubRadarConnectionListItemSchema = z
.object({
name: z.literal("GitHub Radar"),
app: z.literal(AppConnection.GitHubRadar),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]),
methods: z.nativeEnum(GitHubRadarConnectionMethod).array(),
appClientSlug: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.GitHubRadar] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { GitHubConnectionMethod } from "./github-connection-enums";
export const GitHubConnectionOAuthInputCredentialsSchema = z.union([
@@ -161,29 +162,31 @@ export const SanitizedGitHubConnectionSchema = z.discriminatedUnion("method", [
instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(),
host: z.string().optional()
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitHub]} (GitHub App)` })),
BaseGitHubConnectionSchema.extend({
method: z.literal(GitHubConnectionMethod.OAuth),
credentials: z.object({
instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(),
host: z.string().optional()
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitHub]} (OAuth)` })),
BaseGitHubConnectionSchema.extend({
method: z.literal(GitHubConnectionMethod.Pat),
credentials: z.object({
instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(),
host: z.string().optional()
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitHub]} (Personal Access Token)` }))
]);
export const GitHubConnectionListItemSchema = z.object({
name: z.literal("GitHub"),
app: z.literal(AppConnection.GitHub),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]),
methods: z.nativeEnum(GitHubConnectionMethod).array(),
oauthClientId: z.string().optional(),
appClientSlug: z.string().optional()
});
export const GitHubConnectionListItemSchema = z
.object({
name: z.literal("GitHub"),
app: z.literal(AppConnection.GitHub),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]),
methods: z.nativeEnum(GitHubConnectionMethod).array(),
oauthClientId: z.string().optional(),
appClientSlug: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.GitHub] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { GitLabAccessTokenType, GitLabConnectionMethod } from "./gitlab-connection-enums";
export const GitLabConnectionAccessTokenCredentialsSchema = z.object({
@@ -84,13 +85,13 @@ export const SanitizedGitLabConnectionSchema = z.discriminatedUnion("method", [
instanceUrl: true,
accessTokenType: true
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitLab]} (Access Token)` })),
BaseGitLabConnectionSchema.extend({
method: z.literal(GitLabConnectionMethod.OAuth),
credentials: GitLabConnectionOAuthOutputCredentialsSchema.pick({
instanceUrl: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitLab]} (OAuth)` }))
]);
export const ValidateGitLabConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -130,9 +131,11 @@ export const UpdateGitLabConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.GitLab));
export const GitLabConnectionListItemSchema = z.object({
name: z.literal("GitLab"),
app: z.literal(AppConnection.GitLab),
methods: z.nativeEnum(GitLabConnectionMethod).array(),
oauthClientId: z.string().optional()
});
export const GitLabConnectionListItemSchema = z
.object({
name: z.literal("GitLab"),
app: z.literal(AppConnection.GitLab),
methods: z.nativeEnum(GitLabConnectionMethod).array(),
oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.GitLab] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { HCVaultConnectionMethod } from "./hc-vault-connection-enums";
const InstanceUrlSchema = z
@@ -59,7 +60,7 @@ export const SanitizedHCVaultConnectionSchema = z.discriminatedUnion("method", [
namespace: true,
instanceUrl: true
})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.HCVault]} (Access Token)` })),
BaseHCVaultConnectionSchema.extend({
method: z.literal(HCVaultConnectionMethod.AppRole),
credentials: HCVaultConnectionAppRoleCredentialsSchema.pick({
@@ -67,7 +68,7 @@ export const SanitizedHCVaultConnectionSchema = z.discriminatedUnion("method", [
instanceUrl: true,
roleId: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.HCVault]} (App Role)` }))
]);
export const ValidateHCVaultConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -100,8 +101,10 @@ export const UpdateHCVaultConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.HCVault, { supportsGateways: true }));
export const HCVaultConnectionListItemSchema = z.object({
name: z.literal("HCVault"),
app: z.literal(AppConnection.HCVault),
methods: z.nativeEnum(HCVaultConnectionMethod).array()
});
export const HCVaultConnectionListItemSchema = z
.object({
name: z.literal("HCVault"),
app: z.literal(AppConnection.HCVault),
methods: z.nativeEnum(HCVaultConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.HCVault] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { HerokuConnectionMethod } from "./heroku-connection-enums";
export const HerokuConnectionAuthTokenCredentialsSchema = z.object({
@@ -51,11 +52,11 @@ export const SanitizedHerokuConnectionSchema = z.discriminatedUnion("method", [
BaseHerokuConnectionSchema.extend({
method: z.literal(HerokuConnectionMethod.AuthToken),
credentials: HerokuConnectionAuthTokenCredentialsSchema.pick({})
}),
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Heroku]} (Auth Token)` })),
BaseHerokuConnectionSchema.extend({
method: z.literal(HerokuConnectionMethod.OAuth),
credentials: HerokuConnectionOAuthOutputCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Heroku]} (OAuth)` }))
]);
export const ValidateHerokuConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -95,9 +96,11 @@ export const UpdateHerokuConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Heroku));
export const HerokuConnectionListItemSchema = z.object({
name: z.literal("Heroku"),
app: z.literal(AppConnection.Heroku),
methods: z.nativeEnum(HerokuConnectionMethod).array(),
oauthClientId: z.string().optional()
});
export const HerokuConnectionListItemSchema = z
.object({
name: z.literal("Heroku"),
app: z.literal(AppConnection.Heroku),
methods: z.nativeEnum(HerokuConnectionMethod).array(),
oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Heroku] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { HumanitecConnectionMethod } from "./humanitec-connection-enums";
export const HumanitecConnectionAccessTokenCredentialsSchema = z.object({
@@ -25,7 +26,7 @@ export const SanitizedHumanitecConnectionSchema = z.discriminatedUnion("method",
BaseHumanitecConnectionSchema.extend({
method: z.literal(HumanitecConnectionMethod.ApiToken),
credentials: HumanitecConnectionAccessTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Humanitec]} (API Token)` }))
]);
export const ValidateHumanitecConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -51,8 +52,10 @@ export const UpdateHumanitecConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Humanitec));
export const HumanitecConnectionListItemSchema = z.object({
name: z.literal("Humanitec"),
app: z.literal(AppConnection.Humanitec),
methods: z.nativeEnum(HumanitecConnectionMethod).array()
});
export const HumanitecConnectionListItemSchema = z
.object({
name: z.literal("Humanitec"),
app: z.literal(AppConnection.Humanitec),
methods: z.nativeEnum(HumanitecConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Humanitec] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { LaravelForgeConnectionMethod } from "./laravel-forge-connection-enums";
export const LaravelForgeConnectionApiTokenCredentialsSchema = z.object({
@@ -25,7 +26,7 @@ export const SanitizedLaravelForgeConnectionSchema = z.discriminatedUnion("metho
BaseLaravelForgeConnectionSchema.extend({
method: z.literal(LaravelForgeConnectionMethod.ApiToken),
credentials: LaravelForgeConnectionApiTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.LaravelForge]} (API Token)` }))
]);
export const ValidateLaravelForgeConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -51,8 +52,10 @@ export const UpdateLaravelForgeConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.LaravelForge));
export const LaravelForgeConnectionListItemSchema = z.object({
name: z.literal("Laravel Forge"),
app: z.literal(AppConnection.LaravelForge),
methods: z.nativeEnum(LaravelForgeConnectionMethod).array()
});
export const LaravelForgeConnectionListItemSchema = z
.object({
name: z.literal("Laravel Forge"),
app: z.literal(AppConnection.LaravelForge),
methods: z.nativeEnum(LaravelForgeConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.LaravelForge] }));

View File

@@ -1,6 +1,11 @@
import ldap from "ldapjs";
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
import { TGatewayV2ServiceFactory } from "@app/ee/services/gateway-v2/gateway-v2-service";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { GatewayProxyProtocol } from "@app/lib/gateway";
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
import { logger } from "@app/lib/logger";
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
@@ -8,6 +13,66 @@ import { AppConnection } from "@app/services/app-connection/app-connection-enums
import { LdapConnectionMethod } from "./ldap-connection-enums";
import { TLdapConnectionConfig } from "./ldap-connection-types";
const LDAP_TIMEOUT = 15_000;
const parseLdapUrl = (url: string): { protocol: string; host: string; port: number } => {
const urlObj = new URL(url);
const isSSL = urlObj.protocol === "ldaps:";
const defaultPort = isSSL ? 636 : 389;
return {
protocol: urlObj.protocol.replace(":", ""),
host: urlObj.hostname,
port: urlObj.port ? parseInt(urlObj.port, 10) : defaultPort
};
};
const constructLdapUrl = (protocol: string, host: string, port: number): string => {
return `${protocol}://${host}:${port}`;
};
const setupLdapClientHandlers = <T>(
client: ldap.Client,
dn: string,
password: string,
onSuccess: (client: ldap.Client) => T | Promise<T>
): Promise<T> => {
return new Promise<T>((resolve, reject) => {
const handleError = (errorType: string, err: Error) => {
logger.error(err, errorType);
client.destroy();
reject(new Error(`${errorType.replace("LDAP ", "")} - ${err.message}`));
};
client.on("error", (err: Error) => handleError("LDAP Error", err));
client.on("connectError", (err: Error) => handleError("LDAP Connection Error", err));
client.on("connectRefused", (err: Error) => handleError("LDAP Connection Refused", err));
client.on("connectTimeout", (err: Error) => handleError("LDAP Connection Timeout", err));
client.on("connect", () => {
client.bind(dn, password, (err) => {
if (err) {
logger.error(err, "LDAP Bind Error");
client.destroy();
reject(new Error(`Bind Error: ${err.message}`));
return;
}
try {
const result = onSuccess(client);
if (result instanceof Promise) {
result.then((value) => resolve(value)).catch(reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
});
});
});
};
export const getLdapConnectionListItem = () => {
return {
name: "LDAP" as const,
@@ -16,8 +81,6 @@ export const getLdapConnectionListItem = () => {
};
};
const LDAP_TIMEOUT = 15_000;
export const getLdapConnectionClient = async ({
url,
dn,
@@ -25,78 +88,112 @@ export const getLdapConnectionClient = async ({
sslCertificate,
sslRejectUnauthorized = true
}: TLdapConnectionConfig["credentials"]) => {
await blockLocalAndPrivateIpAddresses(url);
await blockLocalAndPrivateIpAddresses(url, false);
const isSSL = url.startsWith("ldaps");
return new Promise<ldap.Client>((resolve, reject) => {
const client = ldap.createClient({
url,
timeout: LDAP_TIMEOUT,
connectTimeout: LDAP_TIMEOUT,
tlsOptions: isSSL
? {
rejectUnauthorized: sslRejectUnauthorized,
ca: sslCertificate ? [sslCertificate] : undefined
}
: undefined
});
client.on("error", (err: Error) => {
logger.error(err, "LDAP Error");
client.destroy();
reject(new Error(`Provider Error - ${err.message}`));
});
client.on("connectError", (err: Error) => {
logger.error(err, "LDAP Connection Error");
client.destroy();
reject(new Error(`Provider Connect Error - ${err.message}`));
});
client.on("connectRefused", (err: Error) => {
logger.error(err, "LDAP Connection Refused");
client.destroy();
reject(new Error(`Provider Connection Refused - ${err.message}`));
});
client.on("connectTimeout", (err: Error) => {
logger.error(err, "LDAP Connection Timeout");
client.destroy();
reject(new Error(`Provider Connection Timeout - ${err.message}`));
});
client.on("connect", () => {
client.bind(dn, password, (err) => {
if (err) {
logger.error(err, "LDAP Bind Error");
reject(new Error(`Bind Error: ${err.message}`));
client.destroy();
const client = ldap.createClient({
url,
timeout: LDAP_TIMEOUT,
connectTimeout: LDAP_TIMEOUT,
tlsOptions: isSSL
? {
rejectUnauthorized: sslRejectUnauthorized,
ca: sslCertificate ? [sslCertificate] : undefined
}
resolve(client);
});
});
: undefined
});
return setupLdapClientHandlers<ldap.Client>(client, dn, password, (ldapClient) => ldapClient);
};
export const validateLdapConnectionCredentials = async ({ credentials }: TLdapConnectionConfig) => {
let client: ldap.Client | undefined;
export const executeWithPotentialGateway = async <T>(
config: TLdapConnectionConfig,
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">,
operation: (client: ldap.Client) => Promise<T>
): Promise<T> => {
const { gatewayId, credentials } = config;
const { protocol, host, port } = parseLdapUrl(credentials.url);
const appCfg = getConfig();
try {
client = await getLdapConnectionClient(credentials);
if (gatewayId && gatewayV2Service) {
await blockLocalAndPrivateIpAddresses(credentials.url, true);
const platformConnectionDetails = await gatewayV2Service.getPlatformConnectionDetailsByGatewayId({
gatewayId,
targetHost: host,
targetPort: port
});
// this shouldn't occur as handle connection error events in client but here as fallback
if (!client.connected) {
throw new BadRequestError({ message: "Unable to connect to LDAP server" });
if (!platformConnectionDetails) {
throw new BadRequestError({ message: "Unable to connect to gateway, no platform connection details found" });
}
return credentials;
} catch (e: unknown) {
throw new BadRequestError({
message: `Unable to validate connection: ${(e as Error).message || "verify credentials"}`
});
return withGatewayV2Proxy(
async (proxyPort) => {
const proxyUrl = constructLdapUrl(protocol, "localhost", proxyPort);
const isSSL = protocol === "ldaps";
const client = ldap.createClient({
url: proxyUrl,
timeout: LDAP_TIMEOUT,
connectTimeout: LDAP_TIMEOUT,
tlsOptions: isSSL
? {
rejectUnauthorized: config.credentials.sslRejectUnauthorized,
ca: config.credentials.sslCertificate ? [config.credentials.sslCertificate] : undefined,
servername: host,
// bypass hostname verification for development
...(appCfg.isDevelopmentMode ? { checkServerIdentity: () => undefined } : {})
}
: undefined
});
return setupLdapClientHandlers<T>(client, credentials.dn, credentials.password, async (ldapClient) => {
try {
return await operation(ldapClient);
} finally {
ldapClient.destroy();
}
});
},
{
protocol: GatewayProxyProtocol.Tcp,
relayHost: platformConnectionDetails.relayHost,
gateway: platformConnectionDetails.gateway,
relay: platformConnectionDetails.relay
}
);
}
// Non-gateway path - calls getLdapConnectionClient which has validation
const client = await getLdapConnectionClient(credentials);
try {
return await operation(client);
} finally {
client?.destroy();
client.destroy();
}
};
export const validateLdapConnectionCredentials = async (
config: TLdapConnectionConfig,
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">
) => {
try {
await executeWithPotentialGateway(config, gatewayV2Service, async (client) => {
// this shouldn't occur as handle connection error events in client but here as fallback
if (!client.connected) {
throw new BadRequestError({ message: "Unable to connect to LDAP server" });
}
});
return config.credentials;
} catch (error) {
throw new BadRequestError({
message: `Unable to validate connection: ${
(error as Error)?.message?.replaceAll(config.credentials.password, "********************") ??
"verify credentials"
}`
});
}
};

View File

@@ -9,6 +9,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { LdapConnectionMethod, LdapProvider } from "./ldap-connection-enums";
export const LdapConnectionSimpleBindCredentialsSchema = z.object({
@@ -61,7 +62,7 @@ export const SanitizedLdapConnectionSchema = z.discriminatedUnion("method", [
sslRejectUnauthorized: true,
sslCertificate: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.LDAP]} (Simple Bind)` }))
]);
export const ValidateLdapConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -74,7 +75,9 @@ export const ValidateLdapConnectionCredentialsSchema = z.discriminatedUnion("met
]);
export const CreateLdapConnectionSchema = ValidateLdapConnectionCredentialsSchema.and(
GenericCreateAppConnectionFieldsSchema(AppConnection.LDAP)
GenericCreateAppConnectionFieldsSchema(AppConnection.LDAP, {
supportsGateways: true
})
);
export const UpdateLdapConnectionSchema = z
@@ -83,12 +86,18 @@ export const UpdateLdapConnectionSchema = z
AppConnections.UPDATE(AppConnection.LDAP).credentials
)
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.LDAP));
.and(
GenericUpdateAppConnectionFieldsSchema(AppConnection.LDAP, {
supportsGateways: true
})
);
export const LdapConnectionListItemSchema = z.object({
name: z.literal("LDAP"),
app: z.literal(AppConnection.LDAP),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]),
methods: z.nativeEnum(LdapConnectionMethod).array()
});
export const LdapConnectionListItemSchema = z
.object({
name: z.literal("LDAP"),
app: z.literal(AppConnection.LDAP),
// the below is preferable but currently breaks with our zod to json schema parser
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]),
methods: z.nativeEnum(LdapConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.LDAP] }));

View File

@@ -17,6 +17,9 @@ export type TLdapConnectionInput = z.infer<typeof CreateLdapConnectionSchema> &
export type TValidateLdapConnectionCredentialsSchema = typeof ValidateLdapConnectionCredentialsSchema;
export type TLdapConnectionConfig = DiscriminativePick<TLdapConnection, "method" | "app" | "credentials"> & {
export type TLdapConnectionConfig = DiscriminativePick<
TLdapConnectionInput,
"method" | "app" | "credentials" | "gatewayId"
> & {
orgId: string;
};

View File

@@ -8,6 +8,7 @@ import {
} from "@app/services/app-connection/app-connection-schemas";
import { AppConnection } from "../app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql";
import { MsSqlConnectionMethod } from "./mssql-connection-enums";
@@ -34,7 +35,7 @@ export const SanitizedMsSqlConnectionSchema = z.discriminatedUnion("method", [
sslRejectUnauthorized: true,
sslCertificate: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.MsSql]} (Username and Password)` }))
]);
export const ValidateMsSqlConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -68,9 +69,11 @@ export const UpdateMsSqlConnectionSchema = z
})
);
export const MsSqlConnectionListItemSchema = z.object({
name: z.literal("Microsoft SQL Server"),
app: z.literal(AppConnection.MsSql),
methods: z.nativeEnum(MsSqlConnectionMethod).array(),
supportsPlatformManagement: z.literal(true)
});
export const MsSqlConnectionListItemSchema = z
.object({
name: z.literal("Microsoft SQL Server"),
app: z.literal(AppConnection.MsSql),
methods: z.nativeEnum(MsSqlConnectionMethod).array(),
supportsPlatformManagement: z.literal(true)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.MsSql] }));

View File

@@ -8,6 +8,7 @@ import {
} from "@app/services/app-connection/app-connection-schemas";
import { AppConnection } from "../app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql";
import { MySqlConnectionMethod } from "./mysql-connection-enums";
@@ -32,7 +33,7 @@ export const SanitizedMySqlConnectionSchema = z.discriminatedUnion("method", [
sslRejectUnauthorized: true,
sslCertificate: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.MySql]} (Username and Password)` }))
]);
export const ValidateMySqlConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -66,9 +67,11 @@ export const UpdateMySqlConnectionSchema = z
})
);
export const MySqlConnectionListItemSchema = z.object({
name: z.literal("MySQL"),
app: z.literal(AppConnection.MySql),
methods: z.nativeEnum(MySqlConnectionMethod).array(),
supportsPlatformManagement: z.literal(true)
});
export const MySqlConnectionListItemSchema = z
.object({
name: z.literal("MySQL"),
app: z.literal(AppConnection.MySql),
methods: z.nativeEnum(MySqlConnectionMethod).array(),
supportsPlatformManagement: z.literal(true)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.MySql] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { NetlifyConnectionMethod } from "./netlify-connection-constants";
export const NetlifyConnectionMethodSchema = z
@@ -36,7 +37,7 @@ export const SanitizedNetlifyConnectionSchema = z.discriminatedUnion("method", [
BaseNetlifyConnectionSchema.extend({
method: NetlifyConnectionMethodSchema,
credentials: NetlifyConnectionAccessTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Netlify]} (Access Token)` }))
]);
export const ValidateNetlifyConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -60,8 +61,10 @@ export const UpdateNetlifyConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Netlify));
export const NetlifyConnectionListItemSchema = z.object({
name: z.literal("Netlify"),
app: z.literal(AppConnection.Netlify),
methods: z.nativeEnum(NetlifyConnectionMethod).array()
});
export const NetlifyConnectionListItemSchema = z
.object({
name: z.literal("Netlify"),
app: z.literal(AppConnection.Netlify),
methods: z.nativeEnum(NetlifyConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Netlify] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { NorthflankConnectionMethod } from "./northflank-connection-enums";
export const NorthflankConnectionApiTokenCredentialsSchema = z.object({
@@ -27,7 +28,7 @@ export const SanitizedNorthflankConnectionSchema = z.discriminatedUnion("method"
BaseNorthflankConnectionSchema.extend({
method: z.literal(NorthflankConnectionMethod.ApiToken),
credentials: NorthflankConnectionApiTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Northflank]} (API Token)` }))
]);
export const ValidateNorthflankConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -53,8 +54,10 @@ export const UpdateNorthflankConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Northflank));
export const NorthflankConnectionListItemSchema = z.object({
name: z.literal("Northflank"),
app: z.literal(AppConnection.Northflank),
methods: z.nativeEnum(NorthflankConnectionMethod).array()
});
export const NorthflankConnectionListItemSchema = z
.object({
name: z.literal("Northflank"),
app: z.literal(AppConnection.Northflank),
methods: z.nativeEnum(NorthflankConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Northflank] }));

View File

@@ -9,6 +9,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { OktaConnectionMethod } from "./okta-connection-enums";
export const OktaConnectionApiTokenCredentialsSchema = z.object({
@@ -40,7 +41,7 @@ export const SanitizedOktaConnectionSchema = z.discriminatedUnion("method", [
credentials: OktaConnectionApiTokenCredentialsSchema.pick({
instanceUrl: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Okta]} (API Token)` }))
]);
export const ValidateOktaConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -62,8 +63,10 @@ export const UpdateOktaConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Okta));
export const OktaConnectionListItemSchema = z.object({
name: z.literal("Okta"),
app: z.literal(AppConnection.Okta),
methods: z.nativeEnum(OktaConnectionMethod).array()
});
export const OktaConnectionListItemSchema = z
.object({
name: z.literal("Okta"),
app: z.literal(AppConnection.Okta),
methods: z.nativeEnum(OktaConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Okta] }));

View File

@@ -8,6 +8,7 @@ import {
} from "@app/services/app-connection/app-connection-schemas";
import { AppConnection } from "../app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql";
import { PostgresConnectionMethod } from "./postgres-connection-enums";
@@ -32,7 +33,7 @@ export const SanitizedPostgresConnectionSchema = z.discriminatedUnion("method",
sslRejectUnauthorized: true,
sslCertificate: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Postgres]} (Username and Password)` }))
]);
export const ValidatePostgresConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -66,9 +67,11 @@ export const UpdatePostgresConnectionSchema = z
})
);
export const PostgresConnectionListItemSchema = z.object({
name: z.literal("PostgreSQL"),
app: z.literal(AppConnection.Postgres),
methods: z.nativeEnum(PostgresConnectionMethod).array(),
supportsPlatformManagement: z.literal(true)
});
export const PostgresConnectionListItemSchema = z
.object({
name: z.literal("PostgreSQL"),
app: z.literal(AppConnection.Postgres),
methods: z.nativeEnum(PostgresConnectionMethod).array(),
supportsPlatformManagement: z.literal(true)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Postgres] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { RailwayConnectionMethod } from "./railway-connection-constants";
export const RailwayConnectionMethodSchema = z
@@ -36,7 +37,7 @@ export const SanitizedRailwayConnectionSchema = z.discriminatedUnion("method", [
BaseRailwayConnectionSchema.extend({
method: RailwayConnectionMethodSchema,
credentials: RailwayConnectionAccessTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Railway]} (Access Token)` }))
]);
export const ValidateRailwayConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -60,11 +61,13 @@ export const UpdateRailwayConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Railway));
export const RailwayConnectionListItemSchema = z.object({
name: z.literal("Railway"),
app: z.literal(AppConnection.Railway),
methods: z.nativeEnum(RailwayConnectionMethod).array()
});
export const RailwayConnectionListItemSchema = z
.object({
name: z.literal("Railway"),
app: z.literal(AppConnection.Railway),
methods: z.nativeEnum(RailwayConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Railway] }));
export const RailwayResourceSchema = z.object({
node: z.object({

View File

@@ -8,6 +8,7 @@ import {
} from "@app/services/app-connection/app-connection-schemas";
import { AppConnection } from "../app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { RedisConnectionMethod } from "./redis-connection-enums";
export const BaseRedisUsernameAndPasswordConnectionSchema = z.object({
@@ -45,7 +46,7 @@ export const SanitizedRedisConnectionSchema = z.discriminatedUnion("method", [
sslRejectUnauthorized: true,
sslCertificate: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Redis]} (Username and Password)` }))
]);
export const ValidateRedisConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -79,9 +80,11 @@ export const UpdateRedisConnectionSchema = z
})
);
export const RedisConnectionListItemSchema = z.object({
name: z.literal("Redis"),
app: z.literal(AppConnection.Redis),
methods: z.nativeEnum(RedisConnectionMethod).array(),
supportsPlatformManagement: z.literal(false)
});
export const RedisConnectionListItemSchema = z
.object({
name: z.literal("Redis"),
app: z.literal(AppConnection.Redis),
methods: z.nativeEnum(RedisConnectionMethod).array(),
supportsPlatformManagement: z.literal(false)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Redis] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { RenderConnectionMethod } from "./render-connection-enums";
export const RenderConnectionApiKeyCredentialsSchema = z.object({
@@ -25,7 +26,7 @@ export const SanitizedRenderConnectionSchema = z.discriminatedUnion("method", [
BaseRenderConnectionSchema.extend({
method: z.literal(RenderConnectionMethod.ApiKey),
credentials: RenderConnectionApiKeyCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Render]} (API Key)` }))
]);
export const ValidateRenderConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -49,8 +50,10 @@ export const UpdateRenderConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Render));
export const RenderConnectionListItemSchema = z.object({
name: z.literal("Render"),
app: z.literal(AppConnection.Render),
methods: z.nativeEnum(RenderConnectionMethod).array()
});
export const RenderConnectionListItemSchema = z
.object({
name: z.literal("Render"),
app: z.literal(AppConnection.Render),
methods: z.nativeEnum(RenderConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Render] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { SupabaseConnectionMethod } from "./supabase-connection-constants";
export const SupabaseConnectionMethodSchema = z
@@ -39,7 +40,7 @@ export const SanitizedSupabaseConnectionSchema = z.discriminatedUnion("method",
credentials: SupabaseConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Supabase]} (Access Token)` }))
]);
export const ValidateSupabaseConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -63,8 +64,10 @@ export const UpdateSupabaseConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Supabase));
export const SupabaseConnectionListItemSchema = z.object({
name: z.literal("Supabase"),
app: z.literal(AppConnection.Supabase),
methods: z.nativeEnum(SupabaseConnectionMethod).array()
});
export const SupabaseConnectionListItemSchema = z
.object({
name: z.literal("Supabase"),
app: z.literal(AppConnection.Supabase),
methods: z.nativeEnum(SupabaseConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Supabase] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { TeamCityConnectionMethod } from "./teamcity-connection-enums";
export const TeamCityConnectionAccessTokenCredentialsSchema = z.object({
@@ -37,7 +38,7 @@ export const SanitizedTeamCityConnectionSchema = z.discriminatedUnion("method",
credentials: TeamCityConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.TeamCity]} (Access Token)` }))
]);
export const ValidateTeamCityConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -63,8 +64,10 @@ export const UpdateTeamCityConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.TeamCity));
export const TeamCityConnectionListItemSchema = z.object({
name: z.literal("TeamCity"),
app: z.literal(AppConnection.TeamCity),
methods: z.nativeEnum(TeamCityConnectionMethod).array()
});
export const TeamCityConnectionListItemSchema = z
.object({
name: z.literal("TeamCity"),
app: z.literal(AppConnection.TeamCity),
methods: z.nativeEnum(TeamCityConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.TeamCity] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { TerraformCloudConnectionMethod } from "./terraform-cloud-connection-enums";
export const TerraformCloudConnectionAccessTokenCredentialsSchema = z.object({
@@ -27,7 +28,7 @@ export const SanitizedTerraformCloudConnectionSchema = z.discriminatedUnion("met
BaseTerraformCloudConnectionSchema.extend({
method: z.literal(TerraformCloudConnectionMethod.ApiToken),
credentials: TerraformCloudConnectionAccessTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.TerraformCloud]} (API Token)` }))
]);
export const ValidateTerraformCloudConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -53,8 +54,10 @@ export const UpdateTerraformCloudConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.TerraformCloud));
export const TerraformCloudConnectionListItemSchema = z.object({
name: z.literal("Terraform Cloud"),
app: z.literal(AppConnection.TerraformCloud),
methods: z.nativeEnum(TerraformCloudConnectionMethod).array()
});
export const TerraformCloudConnectionListItemSchema = z
.object({
name: z.literal("Terraform Cloud"),
app: z.literal(AppConnection.TerraformCloud),
methods: z.nativeEnum(TerraformCloudConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.TerraformCloud] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { VercelConnectionMethod } from "./vercel-connection-enums";
export const VercelConnectionAccessTokenCredentialsSchema = z.object({
@@ -27,7 +28,7 @@ export const SanitizedVercelConnectionSchema = z.discriminatedUnion("method", [
BaseVercelConnectionSchema.extend({
method: z.literal(VercelConnectionMethod.ApiToken),
credentials: VercelConnectionAccessTokenCredentialsSchema.pick({})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Vercel]} (API Token)` }))
]);
export const ValidateVercelConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -51,8 +52,10 @@ export const UpdateVercelConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Vercel));
export const VercelConnectionListItemSchema = z.object({
name: z.literal("Vercel"),
app: z.literal(AppConnection.Vercel),
methods: z.nativeEnum(VercelConnectionMethod).array()
});
export const VercelConnectionListItemSchema = z
.object({
name: z.literal("Vercel"),
app: z.literal(AppConnection.Vercel),
methods: z.nativeEnum(VercelConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Vercel] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { WindmillConnectionMethod } from "./windmill-connection-enums";
export const WindmillConnectionAccessTokenCredentialsSchema = z.object({
@@ -37,7 +38,7 @@ export const SanitizedWindmillConnectionSchema = z.discriminatedUnion("method",
credentials: WindmillConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true
})
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Windmill]} (Access Token)` }))
]);
export const ValidateWindmillConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -63,8 +64,10 @@ export const UpdateWindmillConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Windmill));
export const WindmillConnectionListItemSchema = z.object({
name: z.literal("Windmill"),
app: z.literal(AppConnection.Windmill),
methods: z.nativeEnum(WindmillConnectionMethod).array()
});
export const WindmillConnectionListItemSchema = z
.object({
name: z.literal("Windmill"),
app: z.literal(AppConnection.Windmill),
methods: z.nativeEnum(WindmillConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Windmill] }));

View File

@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { ZabbixConnectionMethod } from "./zabbix-connection-enums";
export const ZabbixConnectionApiTokenCredentialsSchema = z.object({
@@ -31,7 +32,7 @@ export const SanitizedZabbixConnectionSchema = z.discriminatedUnion("method", [
BaseZabbixConnectionSchema.extend({
method: z.literal(ZabbixConnectionMethod.ApiToken),
credentials: ZabbixConnectionApiTokenCredentialsSchema.pick({ instanceUrl: true })
})
}).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Zabbix]} (API Token)` }))
]);
export const ValidateZabbixConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -55,8 +56,10 @@ export const UpdateZabbixConnectionSchema = z
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Zabbix));
export const ZabbixConnectionListItemSchema = z.object({
name: z.literal("Zabbix"),
app: z.literal(AppConnection.Zabbix),
methods: z.nativeEnum(ZabbixConnectionMethod).array()
});
export const ZabbixConnectionListItemSchema = z
.object({
name: z.literal("Zabbix"),
app: z.literal(AppConnection.Zabbix),
methods: z.nativeEnum(ZabbixConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Zabbix] }));

View File

@@ -454,6 +454,30 @@ export const authLoginServiceFactory = ({
});
}
if (organizationId) {
await auditLogService.createAuditLog({
orgId: organizationId,
ipAddress: ip,
userAgent,
userAgentType: getUserAgentType(userAgent),
actor: {
type: ActorType.USER,
metadata: {
email: userEnc.email,
userId: userEnc.userId,
username: userEnc.username,
authMethod
}
},
event: {
type: EventType.USER_LOGIN,
metadata: {
organizationId
}
}
});
}
return {
tokens: {
accessToken: token.access,
@@ -646,6 +670,29 @@ export const authLoginServiceFactory = ({
}
}
await auditLogService.createAuditLog({
orgId: organizationId,
ipAddress,
userAgent,
userAgentType: getUserAgentType(userAgent),
actor: {
type: ActorType.USER,
metadata: {
email: user.email,
userId: user.id,
username: user.username,
authMethod: decodedToken.authMethod
}
},
event: {
type: EventType.SELECT_ORGANIZATION,
metadata: {
organizationId,
organizationName: selectedOrg.name
}
}
});
return {
...tokens,
user,
@@ -1039,6 +1086,33 @@ export const authLoginServiceFactory = ({
organizationId
});
if (organizationId) {
await auditLogService.createAuditLog({
orgId: organizationId,
ipAddress: ip,
userAgent,
userAgentType: getUserAgentType(userAgent),
actor: {
type: ActorType.USER,
metadata: {
email: userEnc.email,
userId: userEnc.userId,
username: userEnc.username,
authMethod: decodedProviderToken.authMethod
}
},
event: {
type: EventType.USER_LOGIN,
metadata: {
organizationId,
...(isAuthMethodSaml(decodedProviderToken.authMethod) && {
authProvider: decodedProviderToken.authMethod
})
}
}
});
}
return { token, isMfaEnabled: false, user: userEnc, decodedProviderToken } as const;
};

View File

@@ -6,6 +6,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
import { UnpackedPermissionSchema, unpackPermissions } from "@app/server/routes/sanitizedSchema/permission";
import { TMembershipRoleDALFactory } from "@app/services/membership/membership-role-dal";
import { ActorType } from "../auth/auth-type";
import { TExternalGroupOrgRoleMappingDALFactory } from "../external-group-org-role-mapping/external-group-org-role-mapping-dal";
@@ -33,6 +34,7 @@ type TRoleServiceFactoryDep = {
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
projectDAL: Pick<TProjectDALFactory, "findById">;
externalGroupOrgRoleMappingDAL: Pick<TExternalGroupOrgRoleMappingDALFactory, "findOne">;
membershipRoleDAL: Pick<TMembershipRoleDALFactory, "find">;
};
export type TRoleServiceFactory = ReturnType<typeof roleServiceFactory>;
@@ -43,7 +45,8 @@ export const roleServiceFactory = ({
projectDAL,
identityDAL,
userDAL,
externalGroupOrgRoleMappingDAL
externalGroupOrgRoleMappingDAL,
membershipRoleDAL
}: TRoleServiceFactoryDep) => {
const orgRoleFactory = newOrgRoleFactory({
permissionService,
@@ -137,6 +140,23 @@ export const roleServiceFactory = ({
});
if (!existingRole) throw new NotFoundError({ message: `Role with ${dto.selector.id} not found` });
const [roleUsageData] = await membershipRoleDAL.find(
{
customRoleId: dto.selector.id
},
{ count: true }
);
if (roleUsageData) {
const count = Number.parseInt(roleUsageData.count, 10);
if (count > 0) {
const plural = count > 1 ? "s" : "";
throw new BadRequestError({
message: `Role is assigned to ${count} identity membership${plural}. Re-assign membership role${plural} to delete this role.`
});
}
}
const [role] = await roleDAL.delete({
id: existingRole.id,
[scope.key]: scope.value

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const OnePassSyncDestinationConfigSchema = z.object({
vaultId: z.string().trim().min(1, "Vault required").describe(SecretSyncs.DESTINATION_CONFIG.ONEPASS.vaultId),
valueLabel: z.string().trim().optional().describe(SecretSyncs.DESTINATION_CONFIG.ONEPASS.valueLabel)
@@ -17,10 +19,12 @@ const OnePassSyncDestinationConfigSchema = z.object({
const OnePassSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const OnePassSyncSchema = BaseSecretSyncSchema(SecretSync.OnePass, OnePassSyncOptionsConfig).extend({
destination: z.literal(SecretSync.OnePass),
destinationConfig: OnePassSyncDestinationConfigSchema
});
export const OnePassSyncSchema = BaseSecretSyncSchema(SecretSync.OnePass, OnePassSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.OnePass),
destinationConfig: OnePassSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OnePass] }));
export const CreateOnePassSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.OnePass,
@@ -36,9 +40,11 @@ export const UpdateOnePassSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: OnePassSyncDestinationConfigSchema.optional()
});
export const OnePassSyncListItemSchema = z.object({
name: z.literal("1Password"),
connection: z.literal(AppConnection.OnePass),
destination: z.literal(SecretSync.OnePass),
canImportSecrets: z.literal(true)
});
export const OnePassSyncListItemSchema = z
.object({
name: z.literal("1Password"),
connection: z.literal(AppConnection.OnePass),
destination: z.literal(SecretSync.OnePass),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OnePass] }));

View File

@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const tagFieldCharacterValidator = characterValidator([
CharacterType.AlphaNumeric,
CharacterType.Spaces,
@@ -105,10 +107,12 @@ export const AwsParameterStoreSyncSchema = BaseSecretSyncSchema(
SecretSync.AWSParameterStore,
AwsParameterStoreSyncOptionsConfig,
AwsParameterStoreSyncOptionsSchema
).extend({
destination: z.literal(SecretSync.AWSParameterStore),
destinationConfig: AwsParameterStoreSyncDestinationConfigSchema
});
)
.extend({
destination: z.literal(SecretSync.AWSParameterStore),
destinationConfig: AwsParameterStoreSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AWSParameterStore] }));
export const CreateAwsParameterStoreSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AWSParameterStore,
@@ -126,9 +130,11 @@ export const UpdateAwsParameterStoreSyncSchema = GenericUpdateSecretSyncFieldsSc
destinationConfig: AwsParameterStoreSyncDestinationConfigSchema.optional()
});
export const AwsParameterStoreSyncListItemSchema = z.object({
name: z.literal("AWS Parameter Store"),
connection: z.literal(AppConnection.AWS),
destination: z.literal(SecretSync.AWSParameterStore),
canImportSecrets: z.literal(true)
});
export const AwsParameterStoreSyncListItemSchema = z
.object({
name: z.literal("AWS Parameter Store"),
connection: z.literal(AppConnection.AWS),
destination: z.literal(SecretSync.AWSParameterStore),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AWSParameterStore] }));

View File

@@ -12,6 +12,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const AwsSecretsManagerSyncDestinationConfigSchema = z
.discriminatedUnion("mappingBehavior", [
z.object({
@@ -119,10 +121,12 @@ export const AwsSecretsManagerSyncSchema = BaseSecretSyncSchema(
SecretSync.AWSSecretsManager,
AwsSecretsManagerSyncOptionsConfig,
AwsSecretsManagerSyncOptionsSchema
).extend({
destination: z.literal(SecretSync.AWSSecretsManager),
destinationConfig: AwsSecretsManagerSyncDestinationConfigSchema
});
)
.extend({
destination: z.literal(SecretSync.AWSSecretsManager),
destinationConfig: AwsSecretsManagerSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AWSSecretsManager] }));
export const CreateAwsSecretsManagerSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AWSSecretsManager,
@@ -164,9 +168,11 @@ export const UpdateAwsSecretsManagerSyncSchema = GenericUpdateSecretSyncFieldsSc
}
});
export const AwsSecretsManagerSyncListItemSchema = z.object({
name: z.literal("AWS Secrets Manager"),
connection: z.literal(AppConnection.AWS),
destination: z.literal(SecretSync.AWSSecretsManager),
canImportSecrets: z.literal(true)
});
export const AwsSecretsManagerSyncListItemSchema = z
.object({
name: z.literal("AWS Secrets Manager"),
connection: z.literal(AppConnection.AWS),
destination: z.literal(SecretSync.AWSSecretsManager),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AWSSecretsManager] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const AzureAppConfigurationSyncDestinationConfigSchema = z.object({
configurationUrl: z
.string()
@@ -23,10 +25,12 @@ const AzureAppConfigurationSyncOptionsConfig: TSyncOptionsConfig = { canImportSe
export const AzureAppConfigurationSyncSchema = BaseSecretSyncSchema(
SecretSync.AzureAppConfiguration,
AzureAppConfigurationSyncOptionsConfig
).extend({
destination: z.literal(SecretSync.AzureAppConfiguration),
destinationConfig: AzureAppConfigurationSyncDestinationConfigSchema
});
)
.extend({
destination: z.literal(SecretSync.AzureAppConfiguration),
destinationConfig: AzureAppConfigurationSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureAppConfiguration] }));
export const CreateAzureAppConfigurationSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AzureAppConfiguration,
@@ -42,9 +46,11 @@ export const UpdateAzureAppConfigurationSyncSchema = GenericUpdateSecretSyncFiel
destinationConfig: AzureAppConfigurationSyncDestinationConfigSchema.optional()
});
export const AzureAppConfigurationSyncListItemSchema = z.object({
name: z.literal("Azure App Configuration"),
connection: z.literal(AppConnection.AzureAppConfiguration),
destination: z.literal(SecretSync.AzureAppConfiguration),
canImportSecrets: z.literal(true)
});
export const AzureAppConfigurationSyncListItemSchema = z
.object({
name: z.literal("Azure App Configuration"),
connection: z.literal(AppConnection.AzureAppConfiguration),
destination: z.literal(SecretSync.AzureAppConfiguration),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureAppConfiguration] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
export const AzureDevOpsSyncDestinationConfigSchema = z.object({
devopsProjectId: z
.string()
@@ -23,10 +25,12 @@ export const AzureDevOpsSyncDestinationConfigSchema = z.object({
const AzureDevOpsSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const AzureDevOpsSyncSchema = BaseSecretSyncSchema(SecretSync.AzureDevOps, AzureDevOpsSyncOptionsConfig).extend({
destination: z.literal(SecretSync.AzureDevOps),
destinationConfig: AzureDevOpsSyncDestinationConfigSchema
});
export const AzureDevOpsSyncSchema = BaseSecretSyncSchema(SecretSync.AzureDevOps, AzureDevOpsSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.AzureDevOps),
destinationConfig: AzureDevOpsSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureDevOps] }));
export const CreateAzureDevOpsSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AzureDevOps,
@@ -42,9 +46,11 @@ export const UpdateAzureDevOpsSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: AzureDevOpsSyncDestinationConfigSchema.optional()
});
export const AzureDevOpsSyncListItemSchema = z.object({
name: z.literal("Azure DevOps"),
connection: z.literal(AppConnection.AzureDevOps),
destination: z.literal(SecretSync.AzureDevOps),
canImportSecrets: z.literal(false)
});
export const AzureDevOpsSyncListItemSchema = z
.object({
name: z.literal("Azure DevOps"),
connection: z.literal(AppConnection.AzureDevOps),
destination: z.literal(SecretSync.AzureDevOps),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureDevOps] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const AzureKeyVaultSyncDestinationConfigSchema = z.object({
vaultBaseUrl: z
.string()
@@ -20,13 +22,12 @@ const AzureKeyVaultSyncDestinationConfigSchema = z.object({
const AzureKeyVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const AzureKeyVaultSyncSchema = BaseSecretSyncSchema(
SecretSync.AzureKeyVault,
AzureKeyVaultSyncOptionsConfig
).extend({
destination: z.literal(SecretSync.AzureKeyVault),
destinationConfig: AzureKeyVaultSyncDestinationConfigSchema
});
export const AzureKeyVaultSyncSchema = BaseSecretSyncSchema(SecretSync.AzureKeyVault, AzureKeyVaultSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.AzureKeyVault),
destinationConfig: AzureKeyVaultSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureKeyVault] }));
export const CreateAzureKeyVaultSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AzureKeyVault,
@@ -42,9 +43,11 @@ export const UpdateAzureKeyVaultSyncSchema = GenericUpdateSecretSyncFieldsSchema
destinationConfig: AzureKeyVaultSyncDestinationConfigSchema.optional()
});
export const AzureKeyVaultSyncListItemSchema = z.object({
name: z.literal("Azure Key Vault"),
connection: z.literal(AppConnection.AzureKeyVault),
destination: z.literal(SecretSync.AzureKeyVault),
canImportSecrets: z.literal(true)
});
export const AzureKeyVaultSyncListItemSchema = z
.object({
name: z.literal("Azure Key Vault"),
connection: z.literal(AppConnection.AzureKeyVault),
destination: z.literal(SecretSync.AzureKeyVault),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureKeyVault] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const BitbucketSyncDestinationConfigSchema = z.object({
repositorySlug: z.string().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.repositorySlug),
environmentId: z.string().optional().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.environmentId),
@@ -18,10 +20,12 @@ const BitbucketSyncDestinationConfigSchema = z.object({
const BitbucketSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const BitbucketSyncSchema = BaseSecretSyncSchema(SecretSync.Bitbucket, BitbucketSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Bitbucket),
destinationConfig: BitbucketSyncDestinationConfigSchema
});
export const BitbucketSyncSchema = BaseSecretSyncSchema(SecretSync.Bitbucket, BitbucketSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Bitbucket),
destinationConfig: BitbucketSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Bitbucket] }));
export const CreateBitbucketSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Bitbucket,
@@ -37,9 +41,11 @@ export const UpdateBitbucketSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: BitbucketSyncDestinationConfigSchema.optional()
});
export const BitbucketSyncListItemSchema = z.object({
name: z.literal("Bitbucket"),
connection: z.literal(AppConnection.Bitbucket),
destination: z.literal(SecretSync.Bitbucket),
canImportSecrets: z.literal(false)
});
export const BitbucketSyncListItemSchema = z
.object({
name: z.literal("Bitbucket"),
connection: z.literal(AppConnection.Bitbucket),
destination: z.literal(SecretSync.Bitbucket),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Bitbucket] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const CamundaSyncDestinationConfigSchema = z.object({
scope: z.string().trim().min(1, "Camunda scope required").describe(SecretSyncs.DESTINATION_CONFIG.CAMUNDA.scope),
clusterUUID: z
@@ -20,10 +22,12 @@ const CamundaSyncDestinationConfigSchema = z.object({
const CamundaSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const CamundaSyncSchema = BaseSecretSyncSchema(SecretSync.Camunda, CamundaSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Camunda),
destinationConfig: CamundaSyncDestinationConfigSchema
});
export const CamundaSyncSchema = BaseSecretSyncSchema(SecretSync.Camunda, CamundaSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Camunda),
destinationConfig: CamundaSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Camunda] }));
export const CreateCamundaSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Camunda,
@@ -39,9 +43,11 @@ export const UpdateCamundaSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: CamundaSyncDestinationConfigSchema.optional()
});
export const CamundaSyncListItemSchema = z.object({
name: z.literal("Camunda"),
connection: z.literal(AppConnection.Camunda),
destination: z.literal(SecretSync.Camunda),
canImportSecrets: z.literal(true)
});
export const CamundaSyncListItemSchema = z
.object({
name: z.literal("Camunda"),
connection: z.literal(AppConnection.Camunda),
destination: z.literal(SecretSync.Camunda),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Camunda] }));

View File

@@ -9,6 +9,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const ChecklySyncDestinationConfigSchema = z.object({
accountId: z.string().min(1, "Account ID is required").max(255, "Account ID must be less than 255 characters"),
accountName: z
@@ -26,10 +28,12 @@ const ChecklySyncDestinationConfigSchema = z.object({
const ChecklySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const ChecklySyncSchema = BaseSecretSyncSchema(SecretSync.Checkly, ChecklySyncOptionsConfig).extend({
destination: z.literal(SecretSync.Checkly),
destinationConfig: ChecklySyncDestinationConfigSchema
});
export const ChecklySyncSchema = BaseSecretSyncSchema(SecretSync.Checkly, ChecklySyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Checkly),
destinationConfig: ChecklySyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Checkly] }));
export const CreateChecklySyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Checkly,
@@ -45,9 +49,11 @@ export const UpdateChecklySyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: ChecklySyncDestinationConfigSchema.optional()
});
export const ChecklySyncListItemSchema = z.object({
name: z.literal("Checkly"),
connection: z.literal(AppConnection.Checkly),
destination: z.literal(SecretSync.Checkly),
canImportSecrets: z.literal(false)
});
export const ChecklySyncListItemSchema = z
.object({
name: z.literal("Checkly"),
connection: z.literal(AppConnection.Checkly),
destination: z.literal(SecretSync.Checkly),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Checkly] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const CloudflarePagesSyncDestinationConfigSchema = z.object({
projectName: z
.string()
@@ -26,10 +28,12 @@ const CloudflarePagesSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets:
export const CloudflarePagesSyncSchema = BaseSecretSyncSchema(
SecretSync.CloudflarePages,
CloudflarePagesSyncOptionsConfig
).extend({
destination: z.literal(SecretSync.CloudflarePages),
destinationConfig: CloudflarePagesSyncDestinationConfigSchema
});
)
.extend({
destination: z.literal(SecretSync.CloudflarePages),
destinationConfig: CloudflarePagesSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.CloudflarePages] }));
export const CreateCloudflarePagesSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.CloudflarePages,
@@ -45,9 +49,11 @@ export const UpdateCloudflarePagesSyncSchema = GenericUpdateSecretSyncFieldsSche
destinationConfig: CloudflarePagesSyncDestinationConfigSchema.optional()
});
export const CloudflarePagesSyncListItemSchema = z.object({
name: z.literal("Cloudflare Pages"),
connection: z.literal(AppConnection.Cloudflare),
destination: z.literal(SecretSync.CloudflarePages),
canImportSecrets: z.literal(false)
});
export const CloudflarePagesSyncListItemSchema = z
.object({
name: z.literal("Cloudflare Pages"),
connection: z.literal(AppConnection.Cloudflare),
destination: z.literal(SecretSync.CloudflarePages),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.CloudflarePages] }));

View File

@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const CloudflareWorkersSyncDestinationConfigSchema = z.object({
scriptId: z
.string()
@@ -28,10 +30,12 @@ const CloudflareWorkersSyncOptionsConfig: TSyncOptionsConfig = { canImportSecret
export const CloudflareWorkersSyncSchema = BaseSecretSyncSchema(
SecretSync.CloudflareWorkers,
CloudflareWorkersSyncOptionsConfig
).extend({
destination: z.literal(SecretSync.CloudflareWorkers),
destinationConfig: CloudflareWorkersSyncDestinationConfigSchema
});
)
.extend({
destination: z.literal(SecretSync.CloudflareWorkers),
destinationConfig: CloudflareWorkersSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.CloudflareWorkers] }));
export const CreateCloudflareWorkersSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.CloudflareWorkers,
@@ -47,9 +51,11 @@ export const UpdateCloudflareWorkersSyncSchema = GenericUpdateSecretSyncFieldsSc
destinationConfig: CloudflareWorkersSyncDestinationConfigSchema.optional()
});
export const CloudflareWorkersSyncListItemSchema = z.object({
name: z.literal("Cloudflare Workers"),
connection: z.literal(AppConnection.Cloudflare),
destination: z.literal(SecretSync.CloudflareWorkers),
canImportSecrets: z.literal(false)
});
export const CloudflareWorkersSyncListItemSchema = z
.object({
name: z.literal("Cloudflare Workers"),
connection: z.literal(AppConnection.Cloudflare),
destination: z.literal(SecretSync.CloudflareWorkers),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.CloudflareWorkers] }));

View File

@@ -10,16 +10,20 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const DatabricksSyncDestinationConfigSchema = z.object({
scope: z.string().trim().min(1, "Databricks scope required").describe(SecretSyncs.DESTINATION_CONFIG.DATABRICKS.scope)
});
const DatabricksSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const DatabricksSyncSchema = BaseSecretSyncSchema(SecretSync.Databricks, DatabricksSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Databricks),
destinationConfig: DatabricksSyncDestinationConfigSchema
});
export const DatabricksSyncSchema = BaseSecretSyncSchema(SecretSync.Databricks, DatabricksSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Databricks),
destinationConfig: DatabricksSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Databricks] }));
export const CreateDatabricksSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Databricks,
@@ -35,9 +39,11 @@ export const UpdateDatabricksSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: DatabricksSyncDestinationConfigSchema.optional()
});
export const DatabricksSyncListItemSchema = z.object({
name: z.literal("Databricks"),
connection: z.literal(AppConnection.Databricks),
destination: z.literal(SecretSync.Databricks),
canImportSecrets: z.literal(false)
});
export const DatabricksSyncListItemSchema = z
.object({
name: z.literal("Databricks"),
connection: z.literal(AppConnection.Databricks),
destination: z.literal(SecretSync.Databricks),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Databricks] }));

View File

@@ -9,6 +9,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const DigitalOceanAppPlatformSyncDestinationConfigSchema = z.object({
appId: z.string().min(1, "Account ID is required").max(255, "Account ID must be less than 255 characters"),
appName: z.string().min(1, "Account Name is required").max(255, "Account Name must be less than 255 characters")
@@ -19,10 +21,12 @@ const DigitalOceanAppPlatformSyncOptionsConfig: TSyncOptionsConfig = { canImport
export const DigitalOceanAppPlatformSyncSchema = BaseSecretSyncSchema(
SecretSync.DigitalOceanAppPlatform,
DigitalOceanAppPlatformSyncOptionsConfig
).extend({
destination: z.literal(SecretSync.DigitalOceanAppPlatform),
destinationConfig: DigitalOceanAppPlatformSyncDestinationConfigSchema
});
)
.extend({
destination: z.literal(SecretSync.DigitalOceanAppPlatform),
destinationConfig: DigitalOceanAppPlatformSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.DigitalOceanAppPlatform] }));
export const CreateDigitalOceanAppPlatformSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.DigitalOceanAppPlatform,
@@ -38,9 +42,11 @@ export const UpdateDigitalOceanAppPlatformSyncSchema = GenericUpdateSecretSyncFi
destinationConfig: DigitalOceanAppPlatformSyncDestinationConfigSchema.optional()
});
export const DigitalOceanAppPlatformSyncListItemSchema = z.object({
name: z.literal("Digital Ocean App Platform"),
connection: z.literal(AppConnection.DigitalOcean),
destination: z.literal(SecretSync.DigitalOceanAppPlatform),
canImportSecrets: z.literal(false)
});
export const DigitalOceanAppPlatformSyncListItemSchema = z
.object({
name: z.literal("Digital Ocean App Platform"),
connection: z.literal(AppConnection.DigitalOcean),
destination: z.literal(SecretSync.DigitalOceanAppPlatform),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.DigitalOceanAppPlatform] }));

View File

@@ -10,16 +10,20 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const FlyioSyncDestinationConfigSchema = z.object({
appId: z.string().trim().min(1, "App required").max(255).describe(SecretSyncs.DESTINATION_CONFIG.FLYIO.appId)
});
const FlyioSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const FlyioSyncSchema = BaseSecretSyncSchema(SecretSync.Flyio, FlyioSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Flyio),
destinationConfig: FlyioSyncDestinationConfigSchema
});
export const FlyioSyncSchema = BaseSecretSyncSchema(SecretSync.Flyio, FlyioSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Flyio),
destinationConfig: FlyioSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Flyio] }));
export const CreateFlyioSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Flyio,
@@ -35,9 +39,11 @@ export const UpdateFlyioSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: FlyioSyncDestinationConfigSchema.optional()
});
export const FlyioSyncListItemSchema = z.object({
name: z.literal("Fly.io"),
connection: z.literal(AppConnection.Flyio),
destination: z.literal(SecretSync.Flyio),
canImportSecrets: z.literal(false)
});
export const FlyioSyncListItemSchema = z
.object({
name: z.literal("Fly.io"),
connection: z.literal(AppConnection.Flyio),
destination: z.literal(SecretSync.Flyio),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Flyio] }));

View File

@@ -10,6 +10,7 @@ import {
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SecretSync } from "../secret-sync-enums";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
import { GCPSecretManagerLocation, GcpSyncScope } from "./gcp-sync-enums";
const GcpSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
@@ -38,10 +39,12 @@ const GcpSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
)
]);
export const GcpSyncSchema = BaseSecretSyncSchema(SecretSync.GCPSecretManager, GcpSyncOptionsConfig).extend({
destination: z.literal(SecretSync.GCPSecretManager),
destinationConfig: GcpSyncDestinationConfigSchema
});
export const GcpSyncSchema = BaseSecretSyncSchema(SecretSync.GCPSecretManager, GcpSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.GCPSecretManager),
destinationConfig: GcpSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GCPSecretManager] }));
export const CreateGcpSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.GCPSecretManager,
@@ -57,9 +60,11 @@ export const UpdateGcpSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: GcpSyncDestinationConfigSchema.optional()
});
export const GcpSyncListItemSchema = z.object({
name: z.literal("GCP Secret Manager"),
connection: z.literal(AppConnection.GCP),
destination: z.literal(SecretSync.GCPSecretManager),
canImportSecrets: z.literal(true)
});
export const GcpSyncListItemSchema = z
.object({
name: z.literal("GCP Secret Manager"),
connection: z.literal(AppConnection.GCP),
destination: z.literal(SecretSync.GCPSecretManager),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GCPSecretManager] }));

View File

@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const GitHubSyncDestinationConfigSchema = z
.discriminatedUnion("scope", [
z.object({
@@ -55,10 +57,12 @@ const GitHubSyncDestinationConfigSchema = z
const GitHubSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const GitHubSyncSchema = BaseSecretSyncSchema(SecretSync.GitHub, GitHubSyncOptionsConfig).extend({
destination: z.literal(SecretSync.GitHub),
destinationConfig: GitHubSyncDestinationConfigSchema
});
export const GitHubSyncSchema = BaseSecretSyncSchema(SecretSync.GitHub, GitHubSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.GitHub),
destinationConfig: GitHubSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GitHub] }));
export const CreateGitHubSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.GitHub,
@@ -74,9 +78,11 @@ export const UpdateGitHubSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: GitHubSyncDestinationConfigSchema.optional()
});
export const GitHubSyncListItemSchema = z.object({
name: z.literal("GitHub"),
connection: z.literal(AppConnection.GitHub),
destination: z.literal(SecretSync.GitHub),
canImportSecrets: z.literal(false)
});
export const GitHubSyncListItemSchema = z
.object({
name: z.literal("GitHub"),
connection: z.literal(AppConnection.GitHub),
destination: z.literal(SecretSync.GitHub),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GitHub] }));

View File

@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
import { GitLabSyncScope } from "./gitlab-sync-enums";
const GitLabSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
@@ -70,10 +71,12 @@ const GitLabSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
const GitLabSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const GitLabSyncSchema = BaseSecretSyncSchema(SecretSync.GitLab, GitLabSyncOptionsConfig).extend({
destination: z.literal(SecretSync.GitLab),
destinationConfig: GitLabSyncDestinationConfigSchema
});
export const GitLabSyncSchema = BaseSecretSyncSchema(SecretSync.GitLab, GitLabSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.GitLab),
destinationConfig: GitLabSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GitLab] }));
export const CreateGitLabSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.GitLab,
@@ -89,9 +92,11 @@ export const UpdateGitLabSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: GitLabSyncDestinationConfigSchema.optional()
});
export const GitLabSyncListItemSchema = z.object({
name: z.literal("GitLab"),
connection: z.literal(AppConnection.GitLab),
destination: z.literal(SecretSync.GitLab),
canImportSecrets: z.literal(false)
});
export const GitLabSyncListItemSchema = z
.object({
name: z.literal("GitLab"),
connection: z.literal(AppConnection.GitLab),
destination: z.literal(SecretSync.GitLab),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GitLab] }));

View File

@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const HCVaultSyncDestinationConfigSchema = z.object({
mount: z
.string()
@@ -33,10 +35,12 @@ const HCVaultSyncDestinationConfigSchema = z.object({
const HCVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const HCVaultSyncSchema = BaseSecretSyncSchema(SecretSync.HCVault, HCVaultSyncOptionsConfig).extend({
destination: z.literal(SecretSync.HCVault),
destinationConfig: HCVaultSyncDestinationConfigSchema
});
export const HCVaultSyncSchema = BaseSecretSyncSchema(SecretSync.HCVault, HCVaultSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.HCVault),
destinationConfig: HCVaultSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.HCVault] }));
export const CreateHCVaultSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.HCVault,
@@ -52,9 +56,11 @@ export const UpdateHCVaultSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: HCVaultSyncDestinationConfigSchema.optional()
});
export const HCVaultSyncListItemSchema = z.object({
name: z.literal("Hashicorp Vault"),
connection: z.literal(AppConnection.HCVault),
destination: z.literal(SecretSync.HCVault),
canImportSecrets: z.literal(true)
});
export const HCVaultSyncListItemSchema = z
.object({
name: z.literal("Hashicorp Vault"),
connection: z.literal(AppConnection.HCVault),
destination: z.literal(SecretSync.HCVault),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.HCVault] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const HerokuSyncDestinationConfigSchema = z.object({
app: z.string().trim().min(1, "App required").describe(SecretSyncs.DESTINATION_CONFIG.HEROKU.app),
appName: z.string().trim().min(1, "App name required").describe(SecretSyncs.DESTINATION_CONFIG.HEROKU.appName)
@@ -17,10 +19,12 @@ const HerokuSyncDestinationConfigSchema = z.object({
const HerokuSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const HerokuSyncSchema = BaseSecretSyncSchema(SecretSync.Heroku, HerokuSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Heroku),
destinationConfig: HerokuSyncDestinationConfigSchema
});
export const HerokuSyncSchema = BaseSecretSyncSchema(SecretSync.Heroku, HerokuSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Heroku),
destinationConfig: HerokuSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Heroku] }));
export const CreateHerokuSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Heroku,
@@ -36,9 +40,11 @@ export const UpdateHerokuSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: HerokuSyncDestinationConfigSchema.optional()
});
export const HerokuSyncListItemSchema = z.object({
name: z.literal("Heroku"),
connection: z.literal(AppConnection.Heroku),
destination: z.literal(SecretSync.Heroku),
canImportSecrets: z.literal(true)
});
export const HerokuSyncListItemSchema = z
.object({
name: z.literal("Heroku"),
connection: z.literal(AppConnection.Heroku),
destination: z.literal(SecretSync.Heroku),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Heroku] }));

View File

@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const HumanitecSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
z.object({
scope: z.literal(HumanitecSyncScope.Application).describe(SecretSyncs.DESTINATION_CONFIG.HUMANITEC.scope),
@@ -27,10 +29,12 @@ const HumanitecSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
const HumanitecSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const HumanitecSyncSchema = BaseSecretSyncSchema(SecretSync.Humanitec, HumanitecSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Humanitec),
destinationConfig: HumanitecSyncDestinationConfigSchema
});
export const HumanitecSyncSchema = BaseSecretSyncSchema(SecretSync.Humanitec, HumanitecSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Humanitec),
destinationConfig: HumanitecSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Humanitec] }));
export const CreateHumanitecSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Humanitec,
@@ -46,9 +50,11 @@ export const UpdateHumanitecSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: HumanitecSyncDestinationConfigSchema.optional()
});
export const HumanitecSyncListItemSchema = z.object({
name: z.literal("Humanitec"),
connection: z.literal(AppConnection.Humanitec),
destination: z.literal(SecretSync.Humanitec),
canImportSecrets: z.literal(false)
});
export const HumanitecSyncListItemSchema = z
.object({
name: z.literal("Humanitec"),
connection: z.literal(AppConnection.Humanitec),
destination: z.literal(SecretSync.Humanitec),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Humanitec] }));

View File

@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const slugValidator = (val: string) => {
return new RE2("^[a-z0-9.-]+$").test(val) && !new RE2(".[-]$").test(val);
};
@@ -38,13 +40,12 @@ const LaravelForgeSyncDestinationConfigSchema = z.object({
const LaravelForgeSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const LaravelForgeSyncSchema = BaseSecretSyncSchema(
SecretSync.LaravelForge,
LaravelForgeSyncOptionsConfig
).extend({
destination: z.literal(SecretSync.LaravelForge),
destinationConfig: LaravelForgeSyncDestinationConfigSchema
});
export const LaravelForgeSyncSchema = BaseSecretSyncSchema(SecretSync.LaravelForge, LaravelForgeSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.LaravelForge),
destinationConfig: LaravelForgeSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.LaravelForge] }));
export const CreateLaravelForgeSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.LaravelForge,
@@ -60,9 +61,11 @@ export const UpdateLaravelForgeSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: LaravelForgeSyncDestinationConfigSchema.optional()
});
export const LaravelForgeSyncListItemSchema = z.object({
name: z.literal("Laravel Forge"),
connection: z.literal(AppConnection.LaravelForge),
destination: z.literal(SecretSync.LaravelForge),
canImportSecrets: z.literal(true)
});
export const LaravelForgeSyncListItemSchema = z
.object({
name: z.literal("Laravel Forge"),
connection: z.literal(AppConnection.LaravelForge),
destination: z.literal(SecretSync.LaravelForge),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.LaravelForge] }));

View File

@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
import { NetlifySyncContext } from "./netlify-sync-constants";
const NetlifySyncDestinationConfigSchema = z.object({
@@ -41,10 +42,12 @@ const NetlifySyncDestinationConfigSchema = z.object({
const NetlifySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const NetlifySyncSchema = BaseSecretSyncSchema(SecretSync.Netlify, NetlifySyncOptionsConfig).extend({
destination: z.literal(SecretSync.Netlify),
destinationConfig: NetlifySyncDestinationConfigSchema
});
export const NetlifySyncSchema = BaseSecretSyncSchema(SecretSync.Netlify, NetlifySyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Netlify),
destinationConfig: NetlifySyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Netlify] }));
export const CreateNetlifySyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Netlify,
@@ -60,9 +63,11 @@ export const UpdateNetlifySyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: NetlifySyncDestinationConfigSchema.optional()
});
export const NetlifySyncListItemSchema = z.object({
name: z.literal("Netlify"),
connection: z.literal(AppConnection.Netlify),
destination: z.literal(SecretSync.Netlify),
canImportSecrets: z.literal(true)
});
export const NetlifySyncListItemSchema = z
.object({
name: z.literal("Netlify"),
connection: z.literal(AppConnection.Netlify),
destination: z.literal(SecretSync.Netlify),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Netlify] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const NorthflankSyncDestinationConfigSchema = z.object({
projectId: z
.string()
@@ -27,10 +29,12 @@ const NorthflankSyncDestinationConfigSchema = z.object({
const NorthflankSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const NorthflankSyncSchema = BaseSecretSyncSchema(SecretSync.Northflank, NorthflankSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Northflank),
destinationConfig: NorthflankSyncDestinationConfigSchema
});
export const NorthflankSyncSchema = BaseSecretSyncSchema(SecretSync.Northflank, NorthflankSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Northflank),
destinationConfig: NorthflankSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Northflank] }));
export const CreateNorthflankSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Northflank,
@@ -46,9 +50,11 @@ export const UpdateNorthflankSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: NorthflankSyncDestinationConfigSchema.optional()
});
export const NorthflankSyncListItemSchema = z.object({
name: z.literal("Northflank"),
connection: z.literal(AppConnection.Northflank),
destination: z.literal(SecretSync.Northflank),
canImportSecrets: z.literal(true)
});
export const NorthflankSyncListItemSchema = z
.object({
name: z.literal("Northflank"),
connection: z.literal(AppConnection.Northflank),
destination: z.literal(SecretSync.Northflank),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Northflank] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const RailwaySyncDestinationConfigSchema = z.object({
projectId: z
.string()
@@ -29,10 +31,12 @@ const RailwaySyncDestinationConfigSchema = z.object({
const RailwaySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const RailwaySyncSchema = BaseSecretSyncSchema(SecretSync.Railway, RailwaySyncOptionsConfig).extend({
destination: z.literal(SecretSync.Railway),
destinationConfig: RailwaySyncDestinationConfigSchema
});
export const RailwaySyncSchema = BaseSecretSyncSchema(SecretSync.Railway, RailwaySyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Railway),
destinationConfig: RailwaySyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Railway] }));
export const CreateRailwaySyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Railway,
@@ -48,9 +52,11 @@ export const UpdateRailwaySyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: RailwaySyncDestinationConfigSchema.optional()
});
export const RailwaySyncListItemSchema = z.object({
name: z.literal("Railway"),
connection: z.literal(AppConnection.Railway),
destination: z.literal(SecretSync.Railway),
canImportSecrets: z.literal(true)
});
export const RailwaySyncListItemSchema = z
.object({
name: z.literal("Railway"),
connection: z.literal(AppConnection.Railway),
destination: z.literal(SecretSync.Railway),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Railway] }));

View File

@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
import { RenderSyncScope, RenderSyncType } from "./render-sync-enums";
const RenderSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
@@ -38,10 +39,12 @@ export const RenderSyncSchema = BaseSecretSyncSchema(
SecretSync.Render,
RenderSyncOptionsConfig,
RenderSyncOptionsSchema
).extend({
destination: z.literal(SecretSync.Render),
destinationConfig: RenderSyncDestinationConfigSchema
});
)
.extend({
destination: z.literal(SecretSync.Render),
destinationConfig: RenderSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Render] }));
export const CreateRenderSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Render,
@@ -59,9 +62,11 @@ export const UpdateRenderSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: RenderSyncDestinationConfigSchema.optional()
});
export const RenderSyncListItemSchema = z.object({
name: z.literal("Render"),
connection: z.literal(AppConnection.Render),
destination: z.literal(SecretSync.Render),
canImportSecrets: z.literal(true)
});
export const RenderSyncListItemSchema = z
.object({
name: z.literal("Render"),
connection: z.literal(AppConnection.Render),
destination: z.literal(SecretSync.Render),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Render] }));

View File

@@ -9,6 +9,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const SupabaseSyncDestinationConfigSchema = z.object({
projectId: z.string().max(255).min(1, "Project ID is required"),
projectName: z.string().max(255).min(1, "Project Name is required")
@@ -16,10 +18,12 @@ const SupabaseSyncDestinationConfigSchema = z.object({
const SupabaseSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const SupabaseSyncSchema = BaseSecretSyncSchema(SecretSync.Supabase, SupabaseSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Supabase),
destinationConfig: SupabaseSyncDestinationConfigSchema
});
export const SupabaseSyncSchema = BaseSecretSyncSchema(SecretSync.Supabase, SupabaseSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Supabase),
destinationConfig: SupabaseSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Supabase] }));
export const CreateSupabaseSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Supabase,
@@ -35,9 +39,11 @@ export const UpdateSupabaseSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: SupabaseSyncDestinationConfigSchema.optional()
});
export const SupabaseSyncListItemSchema = z.object({
name: z.literal("Supabase"),
connection: z.literal(AppConnection.Supabase),
destination: z.literal(SecretSync.Supabase),
canImportSecrets: z.literal(false)
});
export const SupabaseSyncListItemSchema = z
.object({
name: z.literal("Supabase"),
connection: z.literal(AppConnection.Supabase),
destination: z.literal(SecretSync.Supabase),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Supabase] }));

View File

@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const TeamCitySyncDestinationConfigSchema = z.object({
project: z.string().trim().min(1, "Project required").describe(SecretSyncs.DESTINATION_CONFIG.TEAMCITY.project),
buildConfig: z.string().trim().optional().describe(SecretSyncs.DESTINATION_CONFIG.TEAMCITY.buildConfig)
@@ -17,10 +19,12 @@ const TeamCitySyncDestinationConfigSchema = z.object({
const TeamCitySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const TeamCitySyncSchema = BaseSecretSyncSchema(SecretSync.TeamCity, TeamCitySyncOptionsConfig).extend({
destination: z.literal(SecretSync.TeamCity),
destinationConfig: TeamCitySyncDestinationConfigSchema
});
export const TeamCitySyncSchema = BaseSecretSyncSchema(SecretSync.TeamCity, TeamCitySyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.TeamCity),
destinationConfig: TeamCitySyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.TeamCity] }));
export const CreateTeamCitySyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.TeamCity,
@@ -36,9 +40,11 @@ export const UpdateTeamCitySyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: TeamCitySyncDestinationConfigSchema.optional()
});
export const TeamCitySyncListItemSchema = z.object({
name: z.literal("TeamCity"),
connection: z.literal(AppConnection.TeamCity),
destination: z.literal(SecretSync.TeamCity),
canImportSecrets: z.literal(true)
});
export const TeamCitySyncListItemSchema = z
.object({
name: z.literal("TeamCity"),
connection: z.literal(AppConnection.TeamCity),
destination: z.literal(SecretSync.TeamCity),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.TeamCity] }));

View File

@@ -14,6 +14,8 @@ import {
TerraformCloudSyncScope
} from "@app/services/secret-sync/terraform-cloud/terraform-cloud-sync-enums";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const TerraformCloudSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
z.object({
scope: z
@@ -47,13 +49,12 @@ const TerraformCloudSyncDestinationConfigSchema = z.discriminatedUnion("scope",
const TerraformCloudSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const TerraformCloudSyncSchema = BaseSecretSyncSchema(
SecretSync.TerraformCloud,
TerraformCloudSyncOptionsConfig
).extend({
destination: z.literal(SecretSync.TerraformCloud),
destinationConfig: TerraformCloudSyncDestinationConfigSchema
});
export const TerraformCloudSyncSchema = BaseSecretSyncSchema(SecretSync.TerraformCloud, TerraformCloudSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.TerraformCloud),
destinationConfig: TerraformCloudSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.TerraformCloud] }));
export const CreateTerraformCloudSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.TerraformCloud,
@@ -69,9 +70,11 @@ export const UpdateTerraformCloudSyncSchema = GenericUpdateSecretSyncFieldsSchem
destinationConfig: TerraformCloudSyncDestinationConfigSchema.optional()
});
export const TerraformCloudSyncListItemSchema = z.object({
name: z.literal("Terraform Cloud"),
connection: z.literal(AppConnection.TerraformCloud),
destination: z.literal(SecretSync.TerraformCloud),
canImportSecrets: z.literal(false)
});
export const TerraformCloudSyncListItemSchema = z
.object({
name: z.literal("Terraform Cloud"),
connection: z.literal(AppConnection.TerraformCloud),
destination: z.literal(SecretSync.TerraformCloud),
canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.TerraformCloud] }));

View File

@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
import { VercelEnvironmentType } from "./vercel-sync-enums";
const VercelSyncDestinationConfigSchema = z.object({
@@ -22,10 +23,12 @@ const VercelSyncDestinationConfigSchema = z.object({
const VercelSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const VercelSyncSchema = BaseSecretSyncSchema(SecretSync.Vercel, VercelSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Vercel),
destinationConfig: VercelSyncDestinationConfigSchema
});
export const VercelSyncSchema = BaseSecretSyncSchema(SecretSync.Vercel, VercelSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Vercel),
destinationConfig: VercelSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Vercel] }));
export const CreateVercelSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Vercel,
@@ -41,9 +44,11 @@ export const UpdateVercelSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: VercelSyncDestinationConfigSchema.optional()
});
export const VercelSyncListItemSchema = z.object({
name: z.literal("Vercel"),
connection: z.literal(AppConnection.Vercel),
destination: z.literal(SecretSync.Vercel),
canImportSecrets: z.literal(true)
});
export const VercelSyncListItemSchema = z
.object({
name: z.literal("Vercel"),
connection: z.literal(AppConnection.Vercel),
destination: z.literal(SecretSync.Vercel),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Vercel] }));

View File

@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const pathCharacterValidator = characterValidator([
CharacterType.AlphaNumeric,
CharacterType.Underscore,
@@ -39,10 +41,12 @@ const WindmillSyncDestinationConfigSchema = z.object({
const WindmillSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const WindmillSyncSchema = BaseSecretSyncSchema(SecretSync.Windmill, WindmillSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Windmill),
destinationConfig: WindmillSyncDestinationConfigSchema
});
export const WindmillSyncSchema = BaseSecretSyncSchema(SecretSync.Windmill, WindmillSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Windmill),
destinationConfig: WindmillSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Windmill] }));
export const CreateWindmillSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Windmill,
@@ -58,9 +62,11 @@ export const UpdateWindmillSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: WindmillSyncDestinationConfigSchema.optional()
});
export const WindmillSyncListItemSchema = z.object({
name: z.literal("Windmill"),
connection: z.literal(AppConnection.Windmill),
destination: z.literal(SecretSync.Windmill),
canImportSecrets: z.literal(true)
});
export const WindmillSyncListItemSchema = z
.object({
name: z.literal("Windmill"),
connection: z.literal(AppConnection.Windmill),
destination: z.literal(SecretSync.Windmill),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Windmill] }));

View File

@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
import { ZabbixSyncScope } from "./zabbix-sync-enums";
const ZabbixSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
@@ -40,10 +41,12 @@ const ZabbixSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
const ZabbixSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const ZabbixSyncSchema = BaseSecretSyncSchema(SecretSync.Zabbix, ZabbixSyncOptionsConfig).extend({
destination: z.literal(SecretSync.Zabbix),
destinationConfig: ZabbixSyncDestinationConfigSchema
});
export const ZabbixSyncSchema = BaseSecretSyncSchema(SecretSync.Zabbix, ZabbixSyncOptionsConfig)
.extend({
destination: z.literal(SecretSync.Zabbix),
destinationConfig: ZabbixSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Zabbix] }));
export const CreateZabbixSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Zabbix,
@@ -59,9 +62,11 @@ export const UpdateZabbixSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: ZabbixSyncDestinationConfigSchema.optional()
});
export const ZabbixSyncListItemSchema = z.object({
name: z.literal("Zabbix"),
connection: z.literal(AppConnection.Zabbix),
destination: z.literal(SecretSync.Zabbix),
canImportSecrets: z.literal(true)
});
export const ZabbixSyncListItemSchema = z
.object({
name: z.literal("Zabbix"),
connection: z.literal(AppConnection.Zabbix),
destination: z.literal(SecretSync.Zabbix),
canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Zabbix] }));