Merge branch 'main' of https://github.com/Infisical/infisical into chore/unify-license-key

This commit is contained in:
Piyush Gupta
2025-11-17 20:56:01 +05:30
140 changed files with 3071 additions and 998 deletions
+11 -1
View File
@@ -98,7 +98,6 @@
"ms": "^2.1.3", "ms": "^2.1.3",
"mysql2": "^3.9.8", "mysql2": "^3.9.8",
"nanoid": "^3.3.8", "nanoid": "^3.3.8",
"nock": "^14.0.10",
"node-forge": "^1.3.1", "node-forge": "^1.3.1",
"nodemailer": "^6.9.9", "nodemailer": "^6.9.9",
"oci-sdk": "^2.108.0", "oci-sdk": "^2.108.0",
@@ -178,6 +177,7 @@
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-simple-import-sort": "^10.0.0",
"nock": "^14.0.10",
"nodemon": "^3.0.2", "nodemon": "^3.0.2",
"pino-pretty": "^10.2.3", "pino-pretty": "^10.2.3",
"prompt-sync": "^4.2.0", "prompt-sync": "^4.2.0",
@@ -9710,6 +9710,7 @@
"version": "0.39.8", "version": "0.39.8",
"resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.39.8.tgz", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.39.8.tgz",
"integrity": "sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==", "integrity": "sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@open-draft/deferred-promise": "^2.2.0", "@open-draft/deferred-promise": "^2.2.0",
@@ -10736,12 +10737,14 @@
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz",
"integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@open-draft/logger": { "node_modules/@open-draft/logger": {
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz",
"integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"is-node-process": "^1.2.0", "is-node-process": "^1.2.0",
@@ -10752,6 +10755,7 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz",
"integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@opentelemetry/api": { "node_modules/@opentelemetry/api": {
@@ -23002,6 +23006,7 @@
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
"integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/is-number": { "node_modules/is-number": {
@@ -23557,6 +23562,7 @@
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/json5": { "node_modules/json5": {
@@ -25130,6 +25136,7 @@
"version": "14.0.10", "version": "14.0.10",
"resolved": "https://registry.npmjs.org/nock/-/nock-14.0.10.tgz", "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.10.tgz",
"integrity": "sha512-Q7HjkpyPeLa0ZVZC5qpxBt5EyLczFJ91MEewQiIi9taWuA0KB/MDJlUWtON+7dGouVdADTQsf9RA7TZk6D8VMw==", "integrity": "sha512-Q7HjkpyPeLa0ZVZC5qpxBt5EyLczFJ91MEewQiIi9taWuA0KB/MDJlUWtON+7dGouVdADTQsf9RA7TZk6D8VMw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@mswjs/interceptors": "^0.39.5", "@mswjs/interceptors": "^0.39.5",
@@ -27772,6 +27779,7 @@
"version": "1.4.3", "version": "1.4.3",
"resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz",
"integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/p-finally": { "node_modules/p-finally": {
@@ -29179,6 +29187,7 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 8" "node": ">= 8"
@@ -31686,6 +31695,7 @@
"version": "0.5.1", "version": "0.5.1",
"resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
"integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/string_decoder": { "node_modules/string_decoder": {
+1 -1
View File
@@ -123,6 +123,7 @@
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-simple-import-sort": "^10.0.0",
"nock": "^14.0.10",
"nodemon": "^3.0.2", "nodemon": "^3.0.2",
"pino-pretty": "^10.2.3", "pino-pretty": "^10.2.3",
"prompt-sync": "^4.2.0", "prompt-sync": "^4.2.0",
@@ -226,7 +227,6 @@
"ms": "^2.1.3", "ms": "^2.1.3",
"mysql2": "^3.9.8", "mysql2": "^3.9.8",
"nanoid": "^3.3.8", "nanoid": "^3.3.8",
"nock": "^14.0.10",
"node-forge": "^1.3.1", "node-forge": "^1.3.1",
"nodemailer": "^6.9.9", "nodemailer": "^6.9.9",
"oci-sdk": "^2.108.0", "oci-sdk": "^2.108.0",
+3 -10
View File
@@ -435,14 +435,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
projectId: z.string().trim(), projectId: z.string().trim(),
environment: z.string().trim(), environment: z.string().trim(),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash), secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
message: z message: z.string().trim().max(255).optional(),
.string()
.trim()
.min(1)
.max(255)
.refine((message) => message.trim() !== "", {
message: "Commit message cannot be empty"
}),
changes: z.object({ changes: z.object({
secrets: z.object({ secrets: z.object({
create: z create: z
@@ -546,7 +539,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
projectId: req.body.projectId, projectId: req.body.projectId,
environment: req.body.environment, environment: req.body.environment,
secretPath: req.body.secretPath, secretPath: req.body.secretPath,
message: req.body.message, message: req.body.message || "",
changes: { changes: {
secrets: req.body.changes.secrets, secrets: req.body.changes.secrets,
folders: req.body.changes.folders folders: req.body.changes.folders
@@ -564,7 +557,7 @@ export const registerPITRouter = async (server: FastifyZodProvider) => {
projectId: req.body.projectId, projectId: req.body.projectId,
environment: req.body.environment, environment: req.body.environment,
secretPath: req.body.secretPath, secretPath: req.body.secretPath,
message: req.body.message message: req.body.message || ""
} }
} }
}); });
@@ -2,6 +2,7 @@ import z from "zod";
import { AppConnections } from "@app/lib/api-docs"; import { AppConnections } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums"; import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "@app/services/app-connection/app-connection-maps";
import { import {
BaseAppConnectionSchema, BaseAppConnectionSchema,
GenericCreateAppConnectionFieldsSchema, GenericCreateAppConnectionFieldsSchema,
@@ -48,7 +49,7 @@ export const SanitizedChefConnectionSchema = z.discriminatedUnion("method", [
BaseChefConnectionSchema.extend({ BaseChefConnectionSchema.extend({
method: z.literal(ChefConnectionMethod.UserKey), method: z.literal(ChefConnectionMethod.UserKey),
credentials: ChefConnectionUserKeyCredentialsSchema.pick({ serverUrl: true, orgName: true, userName: true }) 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", [ export const ValidateChefConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -70,8 +71,10 @@ export const UpdateChefConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Chef)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Chef));
export const ChefConnectionListItemSchema = z.object({ export const ChefConnectionListItemSchema = z
name: z.literal("Chef"), .object({
app: z.literal(AppConnection.Chef), name: z.literal("Chef"),
methods: z.nativeEnum(ChefConnectionMethod).array() app: z.literal(AppConnection.Chef),
}); methods: z.nativeEnum(ChefConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Chef] }));
@@ -2,6 +2,7 @@ import z from "zod";
import { AppConnections } from "@app/lib/api-docs"; import { AppConnections } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums"; import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "@app/services/app-connection/app-connection-maps";
import { import {
BaseAppConnectionSchema, BaseAppConnectionSchema,
GenericCreateAppConnectionFieldsSchema, GenericCreateAppConnectionFieldsSchema,
@@ -34,7 +35,7 @@ export const SanitizedOCIConnectionSchema = z.discriminatedUnion("method", [
region: true, region: true,
fingerprint: true fingerprint: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.OCI]} (Access Key)` }))
]); ]);
export const ValidateOCIConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateOCIConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -58,8 +59,10 @@ export const UpdateOCIConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OCI)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OCI));
export const OCIConnectionListItemSchema = z.object({ export const OCIConnectionListItemSchema = z
name: z.literal("OCI"), .object({
app: z.literal(AppConnection.OCI), name: z.literal("OCI"),
methods: z.nativeEnum(OCIConnectionMethod).array() app: z.literal(AppConnection.OCI),
}); methods: z.nativeEnum(OCIConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.OCI] }));
@@ -2,6 +2,7 @@ import z from "zod";
import { AppConnections } from "@app/lib/api-docs"; import { AppConnections } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums"; import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "@app/services/app-connection/app-connection-maps";
import { import {
BaseAppConnectionSchema, BaseAppConnectionSchema,
GenericCreateAppConnectionFieldsSchema, GenericCreateAppConnectionFieldsSchema,
@@ -32,7 +33,7 @@ export const SanitizedOracleDBConnectionSchema = z.discriminatedUnion("method",
sslRejectUnauthorized: true, sslRejectUnauthorized: true,
sslCertificate: true sslCertificate: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.OracleDB]} (Username and Password)` }))
]); ]);
export const ValidateOracleDBConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateOracleDBConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -64,9 +65,11 @@ export const UpdateOracleDBConnectionSchema = z
}) })
); );
export const OracleDBConnectionListItemSchema = z.object({ export const OracleDBConnectionListItemSchema = z
name: z.literal("OracleDB"), .object({
app: z.literal(AppConnection.OracleDB), name: z.literal("OracleDB"),
methods: z.nativeEnum(OracleDBConnectionMethod).array(), app: z.literal(AppConnection.OracleDB),
supportsPlatformManagement: z.literal(true) methods: z.nativeEnum(OracleDBConnectionMethod).array(),
}); supportsPlatformManagement: z.literal(true)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.OracleDB] }));
@@ -365,6 +365,8 @@ export enum EventType {
LOAD_PROJECT_KMS_BACKUP = "load-project-kms-backup", LOAD_PROJECT_KMS_BACKUP = "load-project-kms-backup",
ORG_ADMIN_ACCESS_PROJECT = "org-admin-accessed-project", ORG_ADMIN_ACCESS_PROJECT = "org-admin-accessed-project",
ORG_ADMIN_BYPASS_SSO = "org-admin-bypassed-sso", ORG_ADMIN_BYPASS_SSO = "org-admin-bypassed-sso",
USER_LOGIN = "user-login",
SELECT_ORGANIZATION = "select-organization",
CREATE_CERTIFICATE_TEMPLATE = "create-certificate-template", CREATE_CERTIFICATE_TEMPLATE = "create-certificate-template",
UPDATE_CERTIFICATE_TEMPLATE = "update-certificate-template", UPDATE_CERTIFICATE_TEMPLATE = "update-certificate-template",
DELETE_CERTIFICATE_TEMPLATE = "delete-certificate-template", DELETE_CERTIFICATE_TEMPLATE = "delete-certificate-template",
@@ -570,6 +572,7 @@ interface UserActorMetadata {
email?: string | null; email?: string | null;
username: string; username: string;
permission?: Record<string, unknown>; permission?: Record<string, unknown>;
authMethod?: string;
} }
interface ServiceActorMetadata { interface ServiceActorMetadata {
@@ -2657,6 +2660,22 @@ interface OrgAdminBypassSSOEvent {
metadata: Record<string, string>; // no metadata yet 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 { interface CreateCertificateTemplateEstConfig {
type: EventType.CREATE_CERTIFICATE_TEMPLATE_EST_CONFIG; type: EventType.CREATE_CERTIFICATE_TEMPLATE_EST_CONFIG;
metadata: { metadata: {
@@ -4535,4 +4554,6 @@ export type Event =
| UpdateCertificateRenewalConfigEvent | UpdateCertificateRenewalConfigEvent
| DisableCertificateRenewalConfigEvent | DisableCertificateRenewalConfigEvent
| AutomatedRenewCertificate | AutomatedRenewCertificate
| AutomatedRenewCertificateFailed; | AutomatedRenewCertificateFailed
| UserLoginEvent
| SelectOrganizationEvent;
@@ -1,6 +1,8 @@
import { getConfig } from "@app/lib/config/env";
import RE2 from "re2"; import RE2 from "re2";
import { z } from "zod"; import { z } from "zod";
import { getConfig } from "@app/lib/config/env";
import { AcmeAccountDoesNotExistError } from "./pki-acme-errors"; import { AcmeAccountDoesNotExistError } from "./pki-acme-errors";
export const buildUrl = (profileId: string, path: string): string => { export const buildUrl = (profileId: string, path: string): string => {
@@ -12,29 +12,14 @@ import { z, ZodError } from "zod";
import { TPkiAcmeAccounts } from "@app/db/schemas/pki-acme-accounts"; import { TPkiAcmeAccounts } from "@app/db/schemas/pki-acme-accounts";
import { TPkiAcmeAuths } from "@app/db/schemas/pki-acme-auths"; import { TPkiAcmeAuths } from "@app/db/schemas/pki-acme-auths";
import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore"; import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { crypto } from "@app/lib/crypto/cryptography"; import { crypto } from "@app/lib/crypto/cryptography";
import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { isPrivateIp } from "@app/lib/ip/ipRange"; import { isPrivateIp } from "@app/lib/ip/ipRange";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { ActorType } from "@app/services/auth/auth-type";
import { TCertificateProfileDALFactory } from "@app/services/certificate-profile/certificate-profile-dal";
import {
EnrollmentType,
TCertificateProfileWithConfigs
} from "@app/services/certificate-profile/certificate-profile-types";
import { TCertificateV3ServiceFactory } from "@app/services/certificate-v3/certificate-v3-service";
import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
import { getConfig } from "@app/lib/config/env";
import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
import { orderCertificate } from "@app/services/certificate-authority/acme/acme-certificate-authority-fns"; import { ActorType } from "@app/services/auth/auth-type";
import { TCertificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal"; import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
import { CaType } from "@app/services/certificate-authority/certificate-authority-enums";
import { TExternalCertificateAuthorityDALFactory } from "@app/services/certificate-authority/external-certificate-authority-dal";
import { extractCertificateRequestFromCSR } from "@app/services/certificate-common/certificate-csr-utils";
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal"; import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
import { TCertificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal"; import { TCertificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal";
import { import {
@@ -42,6 +27,21 @@ import {
CertKeyUsage, CertKeyUsage,
CertSubjectAlternativeNameType CertSubjectAlternativeNameType
} from "@app/services/certificate/certificate-types"; } from "@app/services/certificate/certificate-types";
import { orderCertificate } from "@app/services/certificate-authority/acme/acme-certificate-authority-fns";
import { TCertificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal";
import { CaType } from "@app/services/certificate-authority/certificate-authority-enums";
import { TExternalCertificateAuthorityDALFactory } from "@app/services/certificate-authority/external-certificate-authority-dal";
import { extractCertificateRequestFromCSR } from "@app/services/certificate-common/certificate-csr-utils";
import { TCertificateProfileDALFactory } from "@app/services/certificate-profile/certificate-profile-dal";
import {
EnrollmentType,
TCertificateProfileWithConfigs
} from "@app/services/certificate-profile/certificate-profile-types";
import { TCertificateV3ServiceFactory } from "@app/services/certificate-v3/certificate-v3-service";
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
import { TLicenseServiceFactory } from "../license/license-service"; import { TLicenseServiceFactory } from "../license/license-service";
import { TPkiAcmeAccountDALFactory } from "./pki-acme-account-dal"; import { TPkiAcmeAccountDALFactory } from "./pki-acme-account-dal";
import { TPkiAcmeAuthDALFactory } from "./pki-acme-auth-dal"; import { TPkiAcmeAuthDALFactory } from "./pki-acme-auth-dal";
@@ -10,7 +10,7 @@ import {
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { DistinguishedNameRegex } from "@app/lib/regex"; import { DistinguishedNameRegex } from "@app/lib/regex";
import { encryptAppConnectionCredentials } from "@app/services/app-connection/app-connection-fns"; 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 { generatePassword } from "../shared/utils";
import { import {
@@ -71,17 +71,18 @@ export const ldapPasswordRotationFactory: TRotationFactory<
TLdapPasswordRotationWithConnection, TLdapPasswordRotationWithConnection,
TLdapPasswordRotationGeneratedCredentials, TLdapPasswordRotationGeneratedCredentials,
TLdapPasswordRotationInput["temporaryParameters"] TLdapPasswordRotationInput["temporaryParameters"]
> = (secretRotation, appConnectionDAL, kmsService) => { > = (secretRotation, appConnectionDAL, kmsService, gatewayService, gatewayV2Service) => {
const { connection, parameters, secretsMapping, activeIndex } = secretRotation; const { connection, parameters, secretsMapping, activeIndex } = secretRotation;
const { dn, passwordRequirements } = parameters; const { dn, passwordRequirements } = parameters;
const $verifyCredentials = async (credentials: Pick<TLdapConnection["credentials"], "dn" | "password">) => { const $verifyCredentials = async (credentials: Pick<TLdapConnection["credentials"], "dn" | "password">) => {
try { try {
const client = await getLdapConnectionClient({ ...connection.credentials, ...credentials }); await executeWithPotentialGateway(
{ ...connection, credentials: { ...connection.credentials, ...credentials } },
client.unbind(); gatewayV2Service,
client.destroy(); async () => {}
);
} catch (error) { } catch (error) {
throw new Error(`Failed to verify credentials - ${(error as Error).message}`); 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"); 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 isConnectionRotation = credentials.dn === dn;
const password = generatePassword(passwordRequirements); const password = generatePassword(passwordRequirements);
let changes: ldap.Change[] | ldap.Change; let changes: ldap.Change[] | ldap.Change;
@@ -147,22 +138,32 @@ export const ldapPasswordRotationFactory: TRotationFactory<
throw new Error(`Unhandled provider: ${credentials.provider as LdapProvider}`); throw new Error(`Unhandled provider: ${credentials.provider as LdapProvider}`);
} }
try { await executeWithPotentialGateway(
const userDn = await getDN(dn, client); {
await new Promise((resolve, reject) => { ...connection,
client.modify(userDn, changes, (err) => { credentials: currentPassword
if (err) { ? {
logger.error(err, "LDAP Password Rotation Failed"); ...credentials,
reject(new Error(`Provider Modify Error: ${err.message}`)); password: currentPassword,
} else { dn
resolve(true); }
} : 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 }); await $verifyCredentials({ dn, password });
@@ -3,6 +3,7 @@ import { z } from "zod";
import { SecretSyncs } from "@app/lib/api-docs"; import { SecretSyncs } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums"; import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { SecretSync } from "@app/services/secret-sync/secret-sync-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 { import {
BaseSecretSyncSchema, BaseSecretSyncSchema,
GenericCreateSecretSyncFieldsSchema, GenericCreateSecretSyncFieldsSchema,
@@ -25,10 +26,12 @@ const ChefSyncDestinationConfigSchema = z.object({
const ChefSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const ChefSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const ChefSyncSchema = BaseSecretSyncSchema(SecretSync.Chef, ChefSyncOptionsConfig).extend({ export const ChefSyncSchema = BaseSecretSyncSchema(SecretSync.Chef, ChefSyncOptionsConfig)
destination: z.literal(SecretSync.Chef), .extend({
destinationConfig: ChefSyncDestinationConfigSchema 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({ export const CreateChefSyncSchema = GenericCreateSecretSyncFieldsSchema(SecretSync.Chef, ChefSyncOptionsConfig).extend({
destinationConfig: ChefSyncDestinationConfigSchema destinationConfig: ChefSyncDestinationConfigSchema
@@ -38,10 +41,12 @@ export const UpdateChefSyncSchema = GenericUpdateSecretSyncFieldsSchema(SecretSy
destinationConfig: ChefSyncDestinationConfigSchema.optional() destinationConfig: ChefSyncDestinationConfigSchema.optional()
}); });
export const ChefSyncListItemSchema = z.object({ export const ChefSyncListItemSchema = z
name: z.literal("Chef"), .object({
connection: z.literal(AppConnection.Chef), name: z.literal("Chef"),
destination: z.literal(SecretSync.Chef), connection: z.literal(AppConnection.Chef),
canImportSecrets: z.literal(true), destination: z.literal(SecretSync.Chef),
enterprise: z.boolean() canImportSecrets: z.literal(true),
}); enterprise: z.boolean()
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Chef] }));
@@ -4,6 +4,7 @@ import { z } from "zod";
import { SecretSyncs } from "@app/lib/api-docs"; import { SecretSyncs } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums"; import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { SecretSync } from "@app/services/secret-sync/secret-sync-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 { import {
BaseSecretSyncSchema, BaseSecretSyncSchema,
GenericCreateSecretSyncFieldsSchema, GenericCreateSecretSyncFieldsSchema,
@@ -43,10 +44,12 @@ const OCIVaultSyncDestinationConfigSchema = z.object({
const OCIVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const OCIVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const OCIVaultSyncSchema = BaseSecretSyncSchema(SecretSync.OCIVault, OCIVaultSyncOptionsConfig).extend({ export const OCIVaultSyncSchema = BaseSecretSyncSchema(SecretSync.OCIVault, OCIVaultSyncOptionsConfig)
destination: z.literal(SecretSync.OCIVault), .extend({
destinationConfig: OCIVaultSyncDestinationConfigSchema destination: z.literal(SecretSync.OCIVault),
}); destinationConfig: OCIVaultSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OCIVault] }));
export const CreateOCIVaultSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateOCIVaultSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.OCIVault, SecretSync.OCIVault,
@@ -62,10 +65,12 @@ export const UpdateOCIVaultSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: OCIVaultSyncDestinationConfigSchema.optional() destinationConfig: OCIVaultSyncDestinationConfigSchema.optional()
}); });
export const OCIVaultSyncListItemSchema = z.object({ export const OCIVaultSyncListItemSchema = z
name: z.literal("OCI Vault"), .object({
connection: z.literal(AppConnection.OCI), name: z.literal("OCI Vault"),
destination: z.literal(SecretSync.OCIVault), connection: z.literal(AppConnection.OCI),
canImportSecrets: z.literal(true), destination: z.literal(SecretSync.OCIVault),
enterprise: z.boolean() canImportSecrets: z.literal(true),
}); enterprise: z.boolean()
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OCIVault] }));
+2 -2
View File
@@ -8,10 +8,10 @@ import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "../errors"; import { BadRequestError } from "../errors";
import { isPrivateIp } from "../ip/ipRange"; import { isPrivateIp } from "../ip/ipRange";
export const blockLocalAndPrivateIpAddresses = async (url: string) => { export const blockLocalAndPrivateIpAddresses = async (url: string, isGateway = false) => {
const appCfg = getConfig(); const appCfg = getConfig();
if (appCfg.isDevelopmentMode) return; if (appCfg.isDevelopmentMode || isGateway) return;
const validUrl = new URL(url); const validUrl = new URL(url);
+2 -1
View File
@@ -643,7 +643,8 @@ export const registerRoutes = async (
projectDAL, projectDAL,
identityDAL, identityDAL,
userDAL, userDAL,
externalGroupOrgRoleMappingDAL externalGroupOrgRoleMappingDAL,
membershipRoleDAL
}); });
const additionalPrivilegeService = additionalPrivilegeServiceFactory({ const additionalPrivilegeService = additionalPrivilegeServiceFactory({
additionalPrivilegeDAL, additionalPrivilegeDAL,
+81 -82
View File
@@ -1,88 +1,87 @@
import { z } from "zod"; // import { z } from "zod";
import { getConfig } from "@app/lib/config/env"; // import { getConfig } from "@app/lib/config/env";
import { ForbiddenRequestError } from "@app/lib/errors"; // import { ForbiddenRequestError } from "@app/lib/errors";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; // import { logger } from "@app/lib/logger";
import { AuthMode } from "@app/services/auth/auth-type"; // import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { logger } from "@app/lib/logger"; // import { AuthMode } from "@app/services/auth/auth-type";
import nock, { Definition } from "nock";
export const registerBddNockRouter = async (server: FastifyZodProvider) => { // export const registerBddNockRouter = async (server: FastifyZodProvider) => {
const checkIfBddNockApiEnabled = () => { // const checkIfBddNockApiEnabled = () => {
const appCfg = getConfig(); // const appCfg = getConfig();
// Note: Please note that this API is only available in development mode and only for BDD tests. // // 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! // // This endpoint should NEVER BE ENABLED IN PRODUCTION!
if (appCfg.NODE_ENV !== "development" || !appCfg.isBddNockApiEnabled) { // if (appCfg.NODE_ENV !== "development" || !appCfg.isBddNockApiEnabled) {
throw new ForbiddenRequestError({ message: "BDD Nock API is not enabled" }); // throw new ForbiddenRequestError({ message: "BDD Nock API is not enabled" });
} // }
}; // };
server.route({ // server.route({
method: "POST", // method: "POST",
url: "/define", // url: "/define",
schema: { // schema: {
body: z.object({ definitions: z.unknown().array() }), // body: z.object({ definitions: z.unknown().array() }),
response: { // response: {
200: z.object({ status: z.string() }) // 200: z.object({ status: z.string() })
} // }
}, // },
onRequest: verifyAuth([AuthMode.JWT]), // onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => { // handler: async (req) => {
checkIfBddNockApiEnabled(); // checkIfBddNockApiEnabled();
const { body } = req; // const { body } = req;
const { definitions } = body; // const { definitions } = body;
logger.info(definitions, "Defining nock"); // logger.info(definitions, "Defining nock");
const processedDefinitions = definitions.map((definition: unknown) => { // const processedDefinitions = definitions.map((definition: unknown) => {
const { path, ...rest } = definition as Definition; // const { path, ...rest } = definition as Definition;
return { // return {
...rest, // ...rest,
path: // path:
path !== undefined && typeof path === "string" // path !== undefined && typeof path === "string"
? path // ? path
: new RegExp((path as unknown as { regex: string }).regex ?? "") // : new RegExp((path as unknown as { regex: string }).regex ?? "")
} as Definition; // } as Definition;
}); // });
nock.define(processedDefinitions); // nock.define(processedDefinitions);
// Ensure we are activating the nocks, because we could have called `nock.restore()` before this call. // // Ensure we are activating the nocks, because we could have called `nock.restore()` before this call.
if (!nock.isActive()) { // if (!nock.isActive()) {
nock.activate(); // nock.activate();
} // }
return { status: "ok" }; // return { status: "ok" };
} // }
}); // });
server.route({ // server.route({
method: "POST", // method: "POST",
url: "/clean-all", // url: "/clean-all",
schema: { // schema: {
response: { // response: {
200: z.object({ status: z.string() }) // 200: z.object({ status: z.string() })
} // }
}, // },
onRequest: verifyAuth([AuthMode.JWT]), // onRequest: verifyAuth([AuthMode.JWT]),
handler: async () => { // handler: async () => {
checkIfBddNockApiEnabled(); // checkIfBddNockApiEnabled();
logger.info("Cleaning all nocks"); // logger.info("Cleaning all nocks");
nock.cleanAll(); // nock.cleanAll();
return { status: "ok" }; // return { status: "ok" };
} // }
}); // });
server.route({ // server.route({
method: "POST", // method: "POST",
url: "/restore", // url: "/restore",
schema: { // schema: {
response: { // response: {
200: z.object({ status: z.string() }) // 200: z.object({ status: z.string() })
} // }
}, // },
onRequest: verifyAuth([AuthMode.JWT]), // onRequest: verifyAuth([AuthMode.JWT]),
handler: async () => { // handler: async () => {
checkIfBddNockApiEnabled(); // checkIfBddNockApiEnabled();
logger.info("Restore network requests from nock"); // logger.info("Restore network requests from nock");
nock.restore(); // nock.restore();
return { status: "ok" }; // return { status: "ok" };
} // }
}); // });
}; // };
+4 -5
View File
@@ -6,10 +6,9 @@ import { registerCmekRouter } from "@app/server/routes/v1/cmek-router";
import { registerDashboardRouter } from "@app/server/routes/v1/dashboard-router"; import { registerDashboardRouter } from "@app/server/routes/v1/dashboard-router";
import { registerSecretSyncRouter, SECRET_SYNC_REGISTER_ROUTER_MAP } from "@app/server/routes/v1/secret-sync-routers"; import { registerSecretSyncRouter, SECRET_SYNC_REGISTER_ROUTER_MAP } from "@app/server/routes/v1/secret-sync-routers";
import { getConfig } from "@app/lib/config/env";
import { registerAdminRouter } from "./admin-router"; import { registerAdminRouter } from "./admin-router";
import { registerAuthRoutes } from "./auth-router"; import { registerAuthRoutes } from "./auth-router";
import { registerBddNockRouter } from "./bdd-nock-router"; // import { registerBddNockRouter } from "./bdd-nock-router";
import { registerProjectBotRouter } from "./bot-router"; import { registerProjectBotRouter } from "./bot-router";
import { registerCaRouter } from "./certificate-authority-router"; import { registerCaRouter } from "./certificate-authority-router";
import { CERTIFICATE_AUTHORITY_REGISTER_ROUTER_MAP } from "./certificate-authority-routers"; import { CERTIFICATE_AUTHORITY_REGISTER_ROUTER_MAP } from "./certificate-authority-routers";
@@ -242,7 +241,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. // 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! // This route should NEVER BE ENABLED IN PRODUCTION!
if (getConfig().isBddNockApiEnabled) { // if (getConfig().isBddNockApiEnabled) {
await server.register(registerBddNockRouter, { prefix: "/bdd-nock" }); // await server.register(registerBddNockRouter, { prefix: "/bdd-nock" });
} // }
}; };
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { OnePassConnectionMethod } from "./1password-connection-enums"; import { OnePassConnectionMethod } from "./1password-connection-enums";
export const OnePassConnectionAccessTokenCredentialsSchema = z.object({ export const OnePassConnectionAccessTokenCredentialsSchema = z.object({
@@ -33,7 +34,7 @@ export const SanitizedOnePassConnectionSchema = z.discriminatedUnion("method", [
credentials: OnePassConnectionAccessTokenCredentialsSchema.pick({ credentials: OnePassConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true instanceUrl: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.OnePass]} (API Token)` }))
]); ]);
export const ValidateOnePassConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateOnePassConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -57,8 +58,10 @@ export const UpdateOnePassConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OnePass)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OnePass));
export const OnePassConnectionListItemSchema = z.object({ export const OnePassConnectionListItemSchema = z
name: z.literal("1Password"), .object({
app: z.literal(AppConnection.OnePass), name: z.literal("1Password"),
methods: z.nativeEnum(OnePassConnectionMethod).array() app: z.literal(AppConnection.OnePass),
}); methods: z.nativeEnum(OnePassConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.OnePass] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { Auth0ConnectionMethod } from "./auth0-connection-enums"; import { Auth0ConnectionMethod } from "./auth0-connection-enums";
export const Auth0ConnectionClientCredentialsInputCredentialsSchema = z.object({ export const Auth0ConnectionClientCredentialsInputCredentialsSchema = z.object({
@@ -59,7 +60,7 @@ export const SanitizedAuth0ConnectionSchema = z.discriminatedUnion("method", [
clientId: true, clientId: true,
audience: true audience: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Auth0]} (Client Credentials)` }))
]); ]);
export const ValidateAuth0ConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateAuth0ConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -85,10 +86,12 @@ export const UpdateAuth0ConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Auth0)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Auth0));
export const Auth0ConnectionListItemSchema = z.object({ export const Auth0ConnectionListItemSchema = z
name: z.literal("Auth0"), .object({
app: z.literal(AppConnection.Auth0), name: z.literal("Auth0"),
// the below is preferable but currently breaks with our zod to json schema parser app: z.literal(AppConnection.Auth0),
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]), // the below is preferable but currently breaks with our zod to json schema parser
methods: z.nativeEnum(Auth0ConnectionMethod).array() // 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] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AwsConnectionMethod } from "./aws-connection-enums"; import { AwsConnectionMethod } from "./aws-connection-enums";
export const AwsConnectionAssumeRoleCredentialsSchema = z.object({ export const AwsConnectionAssumeRoleCredentialsSchema = z.object({
@@ -39,11 +40,11 @@ export const SanitizedAwsConnectionSchema = z.discriminatedUnion("method", [
BaseAwsConnectionSchema.extend({ BaseAwsConnectionSchema.extend({
method: z.literal(AwsConnectionMethod.AssumeRole), method: z.literal(AwsConnectionMethod.AssumeRole),
credentials: AwsConnectionAssumeRoleCredentialsSchema.pick({}) credentials: AwsConnectionAssumeRoleCredentialsSchema.pick({})
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AWS]} (Assume Role)` })),
BaseAwsConnectionSchema.extend({ BaseAwsConnectionSchema.extend({
method: z.literal(AwsConnectionMethod.AccessKey), method: z.literal(AwsConnectionMethod.AccessKey),
credentials: AwsConnectionAccessTokenCredentialsSchema.pick({ accessKeyId: true }) credentials: AwsConnectionAccessTokenCredentialsSchema.pick({ accessKeyId: true })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AWS]} (Access Key)` }))
]); ]);
export const ValidateAwsConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateAwsConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -72,11 +73,13 @@ export const UpdateAwsConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.AWS)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.AWS));
export const AwsConnectionListItemSchema = z.object({ export const AwsConnectionListItemSchema = z
name: z.literal("AWS"), .object({
app: z.literal(AppConnection.AWS), name: z.literal("AWS"),
// the below is preferable but currently breaks with our zod to json schema parser app: z.literal(AppConnection.AWS),
// methods: z.tuple([z.literal(AwsConnectionMethod.AssumeRole), z.literal(AwsConnectionMethod.AccessKey)]), // the below is preferable but currently breaks with our zod to json schema parser
methods: z.nativeEnum(AwsConnectionMethod).array(), // methods: z.tuple([z.literal(AwsConnectionMethod.AssumeRole), z.literal(AwsConnectionMethod.AccessKey)]),
accessKeyId: z.string().optional() methods: z.nativeEnum(AwsConnectionMethod).array(),
}); accessKeyId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AWS] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AzureADCSConnectionMethod } from "./azure-adcs-connection-enums"; import { AzureADCSConnectionMethod } from "./azure-adcs-connection-enums";
export const AzureADCSUsernamePasswordCredentialsSchema = z.object({ export const AzureADCSUsernamePasswordCredentialsSchema = z.object({
@@ -55,7 +56,7 @@ export const SanitizedAzureADCSConnectionSchema = z.discriminatedUnion("method",
sslRejectUnauthorized: true, sslRejectUnauthorized: true,
sslCertificate: true sslCertificate: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureADCS]} (Username and Password)` }))
]); ]);
export const ValidateAzureADCSConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateAzureADCSConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -81,8 +82,10 @@ export const UpdateAzureADCSConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.AzureADCS)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.AzureADCS));
export const AzureADCSConnectionListItemSchema = z.object({ export const AzureADCSConnectionListItemSchema = z
name: z.literal("Azure ADCS"), .object({
app: z.literal(AppConnection.AzureADCS), name: z.literal("Azure ADCS"),
methods: z.nativeEnum(AzureADCSConnectionMethod).array() app: z.literal(AppConnection.AzureADCS),
}); methods: z.nativeEnum(AzureADCSConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureADCS] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } 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"; import { AzureAppConfigurationConnectionMethod } from "./azure-app-configuration-connection-enums";
export const AzureAppConfigurationConnectionOAuthInputCredentialsSchema = z.object({ export const AzureAppConfigurationConnectionOAuthInputCredentialsSchema = z.object({
@@ -104,19 +105,23 @@ export const SanitizedAzureAppConfigurationConnectionSchema = z.discriminatedUni
credentials: AzureAppConfigurationConnectionOAuthOutputCredentialsSchema.pick({ credentials: AzureAppConfigurationConnectionOAuthOutputCredentialsSchema.pick({
tenantId: true tenantId: true
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureAppConfiguration]} (OAuth)` })),
BaseAzureAppConfigurationConnectionSchema.extend({ BaseAzureAppConfigurationConnectionSchema.extend({
method: z.literal(AzureAppConfigurationConnectionMethod.ClientSecret), method: z.literal(AzureAppConfigurationConnectionMethod.ClientSecret),
credentials: AzureAppConfigurationConnectionClientSecretOutputCredentialsSchema.pick({ credentials: AzureAppConfigurationConnectionClientSecretOutputCredentialsSchema.pick({
clientId: true, clientId: true,
tenantId: true tenantId: true
}) })
}) }).describe(
JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureAppConfiguration]} (Client Secret)` })
)
]); ]);
export const AzureAppConfigurationConnectionListItemSchema = z.object({ export const AzureAppConfigurationConnectionListItemSchema = z
name: z.literal("Azure App Configuration"), .object({
app: z.literal(AppConnection.AzureAppConfiguration), name: z.literal("Azure App Configuration"),
methods: z.nativeEnum(AzureAppConfigurationConnectionMethod).array(), app: z.literal(AppConnection.AzureAppConfiguration),
oauthClientId: z.string().optional() methods: z.nativeEnum(AzureAppConfigurationConnectionMethod).array(),
}); oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureAppConfiguration] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } 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"; import { AzureClientSecretsConnectionMethod } from "./azure-client-secrets-connection-enums";
export const AzureClientSecretsConnectionOAuthInputCredentialsSchema = z.object({ export const AzureClientSecretsConnectionOAuthInputCredentialsSchema = z.object({
@@ -162,26 +163,30 @@ export const SanitizedAzureClientSecretsConnectionSchema = z.discriminatedUnion(
credentials: AzureClientSecretsConnectionOAuthOutputCredentialsSchema.pick({ credentials: AzureClientSecretsConnectionOAuthOutputCredentialsSchema.pick({
tenantId: true tenantId: true
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureClientSecrets]} (OAuth)` })),
BaseAzureClientSecretsConnectionSchema.extend({ BaseAzureClientSecretsConnectionSchema.extend({
method: z.literal(AzureClientSecretsConnectionMethod.ClientSecret), method: z.literal(AzureClientSecretsConnectionMethod.ClientSecret),
credentials: AzureClientSecretsConnectionClientSecretOutputCredentialsSchema.pick({ credentials: AzureClientSecretsConnectionClientSecretOutputCredentialsSchema.pick({
clientId: true, clientId: true,
tenantId: true tenantId: true
}) })
}), }).describe(
JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureClientSecrets]} (Client Secret)` })
),
BaseAzureClientSecretsConnectionSchema.extend({ BaseAzureClientSecretsConnectionSchema.extend({
method: z.literal(AzureClientSecretsConnectionMethod.Certificate), method: z.literal(AzureClientSecretsConnectionMethod.Certificate),
credentials: AzureClientSecretsConnectionCertificateOutputCredentialsSchema.pick({ credentials: AzureClientSecretsConnectionCertificateOutputCredentialsSchema.pick({
tenantId: true, tenantId: true,
clientId: true clientId: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureClientSecrets]} (Certificate)` }))
]); ]);
export const AzureClientSecretsConnectionListItemSchema = z.object({ export const AzureClientSecretsConnectionListItemSchema = z
name: z.literal("Azure Client Secrets"), .object({
app: z.literal(AppConnection.AzureClientSecrets), name: z.literal("Azure Client Secrets"),
methods: z.nativeEnum(AzureClientSecretsConnectionMethod).array(), app: z.literal(AppConnection.AzureClientSecrets),
oauthClientId: z.string().optional() methods: z.nativeEnum(AzureClientSecretsConnectionMethod).array(),
}); oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureClientSecrets] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { AzureDevOpsConnectionMethod } from "./azure-devops-enums"; import { AzureDevOpsConnectionMethod } from "./azure-devops-enums";
export const AzureDevOpsConnectionOAuthInputCredentialsSchema = z.object({ export const AzureDevOpsConnectionOAuthInputCredentialsSchema = z.object({
@@ -147,13 +148,13 @@ export const SanitizedAzureDevOpsConnectionSchema = z.discriminatedUnion("method
tenantId: true, tenantId: true,
orgName: true orgName: true
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureDevOps]} (OAuth)` })),
BaseAzureDevOpsConnectionSchema.extend({ BaseAzureDevOpsConnectionSchema.extend({
method: z.literal(AzureDevOpsConnectionMethod.AccessToken), method: z.literal(AzureDevOpsConnectionMethod.AccessToken),
credentials: AzureDevOpsConnectionAccessTokenOutputCredentialsSchema.pick({ credentials: AzureDevOpsConnectionAccessTokenOutputCredentialsSchema.pick({
orgName: true orgName: true
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureDevOps]} (Access Token)` })),
BaseAzureDevOpsConnectionSchema.extend({ BaseAzureDevOpsConnectionSchema.extend({
method: z.literal(AzureDevOpsConnectionMethod.ClientSecret), method: z.literal(AzureDevOpsConnectionMethod.ClientSecret),
credentials: AzureDevOpsConnectionClientSecretOutputCredentialsSchema.pick({ credentials: AzureDevOpsConnectionClientSecretOutputCredentialsSchema.pick({
@@ -161,12 +162,14 @@ export const SanitizedAzureDevOpsConnectionSchema = z.discriminatedUnion("method
tenantId: true, tenantId: true,
orgName: true orgName: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureDevOps]} (Client Secret)` }))
]); ]);
export const AzureDevOpsConnectionListItemSchema = z.object({ export const AzureDevOpsConnectionListItemSchema = z
name: z.literal("Azure DevOps"), .object({
app: z.literal(AppConnection.AzureDevOps), name: z.literal("Azure DevOps"),
methods: z.nativeEnum(AzureDevOpsConnectionMethod).array(), app: z.literal(AppConnection.AzureDevOps),
oauthClientId: z.string().optional() methods: z.nativeEnum(AzureDevOpsConnectionMethod).array(),
}); oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureDevOps] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } 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"; import { AzureKeyVaultConnectionMethod } from "./azure-key-vault-connection-enums";
export const AzureKeyVaultConnectionOAuthInputCredentialsSchema = z.object({ export const AzureKeyVaultConnectionOAuthInputCredentialsSchema = z.object({
@@ -104,19 +105,21 @@ export const SanitizedAzureKeyVaultConnectionSchema = z.discriminatedUnion("meth
credentials: AzureKeyVaultConnectionOAuthOutputCredentialsSchema.pick({ credentials: AzureKeyVaultConnectionOAuthOutputCredentialsSchema.pick({
tenantId: true tenantId: true
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureKeyVault]} (OAuth)` })),
BaseAzureKeyVaultConnectionSchema.extend({ BaseAzureKeyVaultConnectionSchema.extend({
method: z.literal(AzureKeyVaultConnectionMethod.ClientSecret), method: z.literal(AzureKeyVaultConnectionMethod.ClientSecret),
credentials: AzureKeyVaultConnectionClientSecretOutputCredentialsSchema.pick({ credentials: AzureKeyVaultConnectionClientSecretOutputCredentialsSchema.pick({
clientId: true, clientId: true,
tenantId: true tenantId: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.AzureKeyVault]} (Client Secret)` }))
]); ]);
export const AzureKeyVaultConnectionListItemSchema = z.object({ export const AzureKeyVaultConnectionListItemSchema = z
name: z.literal("Azure Key Vault"), .object({
app: z.literal(AppConnection.AzureKeyVault), name: z.literal("Azure Key Vault"),
methods: z.nativeEnum(AzureKeyVaultConnectionMethod).array(), app: z.literal(AppConnection.AzureKeyVault),
oauthClientId: z.string().optional() methods: z.nativeEnum(AzureKeyVaultConnectionMethod).array(),
}); oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.AzureKeyVault] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { BitbucketConnectionMethod } from "./bitbucket-connection-enums"; import { BitbucketConnectionMethod } from "./bitbucket-connection-enums";
export const BitbucketConnectionAccessTokenCredentialsSchema = z.object({ export const BitbucketConnectionAccessTokenCredentialsSchema = z.object({
@@ -39,7 +40,7 @@ export const SanitizedBitbucketConnectionSchema = z.discriminatedUnion("method",
credentials: BitbucketConnectionAccessTokenCredentialsSchema.pick({ credentials: BitbucketConnectionAccessTokenCredentialsSchema.pick({
email: true email: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Bitbucket]} (API Token)` }))
]); ]);
export const ValidateBitbucketConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateBitbucketConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -65,8 +66,10 @@ export const UpdateBitbucketConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Bitbucket)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Bitbucket));
export const BitbucketConnectionListItemSchema = z.object({ export const BitbucketConnectionListItemSchema = z
name: z.literal("Bitbucket"), .object({
app: z.literal(AppConnection.Bitbucket), name: z.literal("Bitbucket"),
methods: z.nativeEnum(BitbucketConnectionMethod).array() app: z.literal(AppConnection.Bitbucket),
}); methods: z.nativeEnum(BitbucketConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Bitbucket] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { CamundaConnectionMethod } from "./camunda-connection-enums"; import { CamundaConnectionMethod } from "./camunda-connection-enums";
const BaseCamundaConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.Camunda) }); const BaseCamundaConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.Camunda) });
@@ -44,7 +45,7 @@ export const SanitizedCamundaConnectionSchema = z.discriminatedUnion("method", [
credentials: CamundaConnectionClientCredentialsOutputCredentialsSchema.pick({ credentials: CamundaConnectionClientCredentialsOutputCredentialsSchema.pick({
clientId: true clientId: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Camunda]} (Client Credentials)` }))
]); ]);
export const ValidateCamundaConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateCamundaConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -70,8 +71,10 @@ export const UpdateCamundaConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Camunda)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Camunda));
export const CamundaConnectionListItemSchema = z.object({ export const CamundaConnectionListItemSchema = z
name: z.literal("Camunda"), .object({
app: z.literal(AppConnection.Camunda), name: z.literal("Camunda"),
methods: z.nativeEnum(CamundaConnectionMethod).array() app: z.literal(AppConnection.Camunda),
}); methods: z.nativeEnum(CamundaConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Camunda] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { ChecklyConnectionMethod } from "./checkly-connection-constants"; import { ChecklyConnectionMethod } from "./checkly-connection-constants";
export const ChecklyConnectionMethodSchema = z export const ChecklyConnectionMethodSchema = z
@@ -31,7 +32,7 @@ export const SanitizedChecklyConnectionSchema = z.discriminatedUnion("method", [
BaseChecklyConnectionSchema.extend({ BaseChecklyConnectionSchema.extend({
method: ChecklyConnectionMethodSchema, method: ChecklyConnectionMethodSchema,
credentials: ChecklyConnectionAccessTokenCredentialsSchema.pick({}) credentials: ChecklyConnectionAccessTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Checkly]} (Access Token)` }))
]); ]);
export const ValidateChecklyConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateChecklyConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -55,8 +56,10 @@ export const UpdateChecklyConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Checkly)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Checkly));
export const ChecklyConnectionListItemSchema = z.object({ export const ChecklyConnectionListItemSchema = z
name: z.literal("Checkly"), .object({
app: z.literal(AppConnection.Checkly), name: z.literal("Checkly"),
methods: z.nativeEnum(ChecklyConnectionMethod).array() app: z.literal(AppConnection.Checkly),
}); methods: z.nativeEnum(ChecklyConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Checkly] }));
@@ -9,6 +9,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { CloudflareConnectionMethod } from "./cloudflare-connection-enum"; import { CloudflareConnectionMethod } from "./cloudflare-connection-enum";
const accountIdCharacterValidator = characterValidator([ const accountIdCharacterValidator = characterValidator([
@@ -41,7 +42,7 @@ export const SanitizedCloudflareConnectionSchema = z.discriminatedUnion("method"
BaseCloudflareConnectionSchema.extend({ BaseCloudflareConnectionSchema.extend({
method: z.literal(CloudflareConnectionMethod.APIToken), method: z.literal(CloudflareConnectionMethod.APIToken),
credentials: CloudflareConnectionApiTokenCredentialsSchema.pick({ accountId: true }) credentials: CloudflareConnectionApiTokenCredentialsSchema.pick({ accountId: true })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Cloudflare]} (API Token)` }))
]); ]);
export const ValidateCloudflareConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateCloudflareConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -67,8 +68,10 @@ export const UpdateCloudflareConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Cloudflare)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Cloudflare));
export const CloudflareConnectionListItemSchema = z.object({ export const CloudflareConnectionListItemSchema = z
name: z.literal("Cloudflare"), .object({
app: z.literal(AppConnection.Cloudflare), name: z.literal("Cloudflare"),
methods: z.nativeEnum(CloudflareConnectionMethod).array() app: z.literal(AppConnection.Cloudflare),
}); methods: z.nativeEnum(CloudflareConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Cloudflare] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { DatabricksConnectionMethod } from "./databricks-connection-enums"; import { DatabricksConnectionMethod } from "./databricks-connection-enums";
export const DatabricksConnectionServicePrincipalInputCredentialsSchema = z.object({ export const DatabricksConnectionServicePrincipalInputCredentialsSchema = z.object({
@@ -42,7 +43,7 @@ export const SanitizedDatabricksConnectionSchema = z.discriminatedUnion("method"
clientId: true, clientId: true,
workspaceUrl: true workspaceUrl: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Databricks]} (Service Principal)` }))
]); ]);
export const ValidateDatabricksConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateDatabricksConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -68,10 +69,12 @@ export const UpdateDatabricksConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Databricks)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Databricks));
export const DatabricksConnectionListItemSchema = z.object({ export const DatabricksConnectionListItemSchema = z
name: z.literal("Databricks"), .object({
app: z.literal(AppConnection.Databricks), name: z.literal("Databricks"),
// the below is preferable but currently breaks with our zod to json schema parser app: z.literal(AppConnection.Databricks),
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]), // the below is preferable but currently breaks with our zod to json schema parser
methods: z.nativeEnum(DatabricksConnectionMethod).array() // 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] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { DigitalOceanConnectionMethod } from "./digital-ocean-connection-constants"; import { DigitalOceanConnectionMethod } from "./digital-ocean-connection-constants";
export const DigitalOceanConnectionMethodSchema = z export const DigitalOceanConnectionMethodSchema = z
@@ -36,7 +37,7 @@ export const SanitizedDigitalOceanConnectionSchema = z.discriminatedUnion("metho
BaseDigitalOceanConnectionSchema.extend({ BaseDigitalOceanConnectionSchema.extend({
method: DigitalOceanConnectionMethodSchema, method: DigitalOceanConnectionMethodSchema,
credentials: DigitalOceanConnectionAccessTokenCredentialsSchema.pick({}) credentials: DigitalOceanConnectionAccessTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.DigitalOcean]} (Access Token)` }))
]); ]);
export const ValidateDigitalOceanConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateDigitalOceanConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -60,8 +61,10 @@ export const UpdateDigitalOceanConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.DigitalOcean)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.DigitalOcean));
export const DigitalOceanConnectionListItemSchema = z.object({ export const DigitalOceanConnectionListItemSchema = z
name: z.literal("Digital Ocean"), .object({
app: z.literal(AppConnection.DigitalOcean), name: z.literal("Digital Ocean"),
methods: z.nativeEnum(DigitalOceanConnectionMethod).array() app: z.literal(AppConnection.DigitalOcean),
}); methods: z.nativeEnum(DigitalOceanConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.DigitalOcean] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { FlyioConnectionMethod } from "./flyio-connection-enums"; import { FlyioConnectionMethod } from "./flyio-connection-enums";
export const FlyioConnectionAccessTokenCredentialsSchema = z.object({ export const FlyioConnectionAccessTokenCredentialsSchema = z.object({
@@ -31,7 +32,7 @@ export const SanitizedFlyioConnectionSchema = z.discriminatedUnion("method", [
BaseFlyioConnectionSchema.extend({ BaseFlyioConnectionSchema.extend({
method: z.literal(FlyioConnectionMethod.AccessToken), method: z.literal(FlyioConnectionMethod.AccessToken),
credentials: FlyioConnectionAccessTokenCredentialsSchema.pick({}) credentials: FlyioConnectionAccessTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Flyio]} (Access Token)` }))
]); ]);
export const ValidateFlyioConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateFlyioConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -55,8 +56,10 @@ export const UpdateFlyioConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Flyio)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Flyio));
export const FlyioConnectionListItemSchema = z.object({ export const FlyioConnectionListItemSchema = z
name: z.literal("Fly.io"), .object({
app: z.literal(AppConnection.Flyio), name: z.literal("Fly.io"),
methods: z.nativeEnum(FlyioConnectionMethod).array() app: z.literal(AppConnection.Flyio),
}); methods: z.nativeEnum(FlyioConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Flyio] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { GcpConnectionMethod } from "./gcp-connection-enums"; import { GcpConnectionMethod } from "./gcp-connection-enums";
export const GcpConnectionServiceAccountImpersonationCredentialsSchema = z.object({ export const GcpConnectionServiceAccountImpersonationCredentialsSchema = z.object({
@@ -30,7 +31,9 @@ export const SanitizedGcpConnectionSchema = z.discriminatedUnion("method", [
BaseGcpConnectionSchema.extend({ BaseGcpConnectionSchema.extend({
method: z.literal(GcpConnectionMethod.ServiceAccountImpersonation), method: z.literal(GcpConnectionMethod.ServiceAccountImpersonation),
credentials: GcpConnectionServiceAccountImpersonationCredentialsSchema.pick({}) credentials: GcpConnectionServiceAccountImpersonationCredentialsSchema.pick({})
}) }).describe(
JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GCP]} (Service Account Impersonation)` })
)
]); ]);
export const ValidateGcpConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateGcpConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -56,10 +59,12 @@ export const UpdateGcpConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.GCP)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.GCP));
export const GcpConnectionListItemSchema = z.object({ export const GcpConnectionListItemSchema = z
name: z.literal("GCP"), .object({
app: z.literal(AppConnection.GCP), name: z.literal("GCP"),
// the below is preferable but currently breaks with our zod to json schema parser app: z.literal(AppConnection.GCP),
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]), // the below is preferable but currently breaks with our zod to json schema parser
methods: z.nativeEnum(GcpConnectionMethod).array() // 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] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { GitHubRadarConnectionMethod } from "./github-radar-connection-enums"; import { GitHubRadarConnectionMethod } from "./github-radar-connection-enums";
export const GitHubRadarConnectionInputCredentialsSchema = z.object({ export const GitHubRadarConnectionInputCredentialsSchema = z.object({
@@ -53,14 +54,16 @@ export const SanitizedGitHubRadarConnectionSchema = z.discriminatedUnion("method
BaseGitHubRadarConnectionSchema.extend({ BaseGitHubRadarConnectionSchema.extend({
method: z.literal(GitHubRadarConnectionMethod.App), method: z.literal(GitHubRadarConnectionMethod.App),
credentials: GitHubRadarConnectionOutputCredentialsSchema.pick({}) credentials: GitHubRadarConnectionOutputCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitHubRadar]} (GitHub App)` }))
]); ]);
export const GitHubRadarConnectionListItemSchema = z.object({ export const GitHubRadarConnectionListItemSchema = z
name: z.literal("GitHub Radar"), .object({
app: z.literal(AppConnection.GitHubRadar), name: z.literal("GitHub Radar"),
// the below is preferable but currently breaks with our zod to json schema parser app: z.literal(AppConnection.GitHubRadar),
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]), // the below is preferable but currently breaks with our zod to json schema parser
methods: z.nativeEnum(GitHubRadarConnectionMethod).array(), // methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]),
appClientSlug: z.string().optional() methods: z.nativeEnum(GitHubRadarConnectionMethod).array(),
}); appClientSlug: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.GitHubRadar] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { GitHubConnectionMethod } from "./github-connection-enums"; import { GitHubConnectionMethod } from "./github-connection-enums";
export const GitHubConnectionOAuthInputCredentialsSchema = z.union([ 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(), instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(),
host: z.string().optional() host: z.string().optional()
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitHub]} (GitHub App)` })),
BaseGitHubConnectionSchema.extend({ BaseGitHubConnectionSchema.extend({
method: z.literal(GitHubConnectionMethod.OAuth), method: z.literal(GitHubConnectionMethod.OAuth),
credentials: z.object({ credentials: z.object({
instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(), instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(),
host: z.string().optional() host: z.string().optional()
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitHub]} (OAuth)` })),
BaseGitHubConnectionSchema.extend({ BaseGitHubConnectionSchema.extend({
method: z.literal(GitHubConnectionMethod.Pat), method: z.literal(GitHubConnectionMethod.Pat),
credentials: z.object({ credentials: z.object({
instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(), instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(),
host: z.string().optional() host: z.string().optional()
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitHub]} (Personal Access Token)` }))
]); ]);
export const GitHubConnectionListItemSchema = z.object({ export const GitHubConnectionListItemSchema = z
name: z.literal("GitHub"), .object({
app: z.literal(AppConnection.GitHub), name: z.literal("GitHub"),
// the below is preferable but currently breaks with our zod to json schema parser app: z.literal(AppConnection.GitHub),
// methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]), // the below is preferable but currently breaks with our zod to json schema parser
methods: z.nativeEnum(GitHubConnectionMethod).array(), // methods: z.tuple([z.literal(GitHubConnectionMethod.App), z.literal(GitHubConnectionMethod.OAuth)]),
oauthClientId: z.string().optional(), methods: z.nativeEnum(GitHubConnectionMethod).array(),
appClientSlug: z.string().optional() oauthClientId: z.string().optional(),
}); appClientSlug: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.GitHub] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { GitLabAccessTokenType, GitLabConnectionMethod } from "./gitlab-connection-enums"; import { GitLabAccessTokenType, GitLabConnectionMethod } from "./gitlab-connection-enums";
export const GitLabConnectionAccessTokenCredentialsSchema = z.object({ export const GitLabConnectionAccessTokenCredentialsSchema = z.object({
@@ -84,13 +85,13 @@ export const SanitizedGitLabConnectionSchema = z.discriminatedUnion("method", [
instanceUrl: true, instanceUrl: true,
accessTokenType: true accessTokenType: true
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitLab]} (Access Token)` })),
BaseGitLabConnectionSchema.extend({ BaseGitLabConnectionSchema.extend({
method: z.literal(GitLabConnectionMethod.OAuth), method: z.literal(GitLabConnectionMethod.OAuth),
credentials: GitLabConnectionOAuthOutputCredentialsSchema.pick({ credentials: GitLabConnectionOAuthOutputCredentialsSchema.pick({
instanceUrl: true instanceUrl: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.GitLab]} (OAuth)` }))
]); ]);
export const ValidateGitLabConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateGitLabConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -130,9 +131,11 @@ export const UpdateGitLabConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.GitLab)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.GitLab));
export const GitLabConnectionListItemSchema = z.object({ export const GitLabConnectionListItemSchema = z
name: z.literal("GitLab"), .object({
app: z.literal(AppConnection.GitLab), name: z.literal("GitLab"),
methods: z.nativeEnum(GitLabConnectionMethod).array(), app: z.literal(AppConnection.GitLab),
oauthClientId: z.string().optional() methods: z.nativeEnum(GitLabConnectionMethod).array(),
}); oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.GitLab] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { HCVaultConnectionMethod } from "./hc-vault-connection-enums"; import { HCVaultConnectionMethod } from "./hc-vault-connection-enums";
const InstanceUrlSchema = z const InstanceUrlSchema = z
@@ -59,7 +60,7 @@ export const SanitizedHCVaultConnectionSchema = z.discriminatedUnion("method", [
namespace: true, namespace: true,
instanceUrl: true instanceUrl: true
}) })
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.HCVault]} (Access Token)` })),
BaseHCVaultConnectionSchema.extend({ BaseHCVaultConnectionSchema.extend({
method: z.literal(HCVaultConnectionMethod.AppRole), method: z.literal(HCVaultConnectionMethod.AppRole),
credentials: HCVaultConnectionAppRoleCredentialsSchema.pick({ credentials: HCVaultConnectionAppRoleCredentialsSchema.pick({
@@ -67,7 +68,7 @@ export const SanitizedHCVaultConnectionSchema = z.discriminatedUnion("method", [
instanceUrl: true, instanceUrl: true,
roleId: true roleId: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.HCVault]} (App Role)` }))
]); ]);
export const ValidateHCVaultConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateHCVaultConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -100,8 +101,10 @@ export const UpdateHCVaultConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.HCVault, { supportsGateways: true })); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.HCVault, { supportsGateways: true }));
export const HCVaultConnectionListItemSchema = z.object({ export const HCVaultConnectionListItemSchema = z
name: z.literal("HCVault"), .object({
app: z.literal(AppConnection.HCVault), name: z.literal("HCVault"),
methods: z.nativeEnum(HCVaultConnectionMethod).array() app: z.literal(AppConnection.HCVault),
}); methods: z.nativeEnum(HCVaultConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.HCVault] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { HerokuConnectionMethod } from "./heroku-connection-enums"; import { HerokuConnectionMethod } from "./heroku-connection-enums";
export const HerokuConnectionAuthTokenCredentialsSchema = z.object({ export const HerokuConnectionAuthTokenCredentialsSchema = z.object({
@@ -51,11 +52,11 @@ export const SanitizedHerokuConnectionSchema = z.discriminatedUnion("method", [
BaseHerokuConnectionSchema.extend({ BaseHerokuConnectionSchema.extend({
method: z.literal(HerokuConnectionMethod.AuthToken), method: z.literal(HerokuConnectionMethod.AuthToken),
credentials: HerokuConnectionAuthTokenCredentialsSchema.pick({}) credentials: HerokuConnectionAuthTokenCredentialsSchema.pick({})
}), }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Heroku]} (Auth Token)` })),
BaseHerokuConnectionSchema.extend({ BaseHerokuConnectionSchema.extend({
method: z.literal(HerokuConnectionMethod.OAuth), method: z.literal(HerokuConnectionMethod.OAuth),
credentials: HerokuConnectionOAuthOutputCredentialsSchema.pick({}) credentials: HerokuConnectionOAuthOutputCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Heroku]} (OAuth)` }))
]); ]);
export const ValidateHerokuConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateHerokuConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -95,9 +96,11 @@ export const UpdateHerokuConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Heroku)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Heroku));
export const HerokuConnectionListItemSchema = z.object({ export const HerokuConnectionListItemSchema = z
name: z.literal("Heroku"), .object({
app: z.literal(AppConnection.Heroku), name: z.literal("Heroku"),
methods: z.nativeEnum(HerokuConnectionMethod).array(), app: z.literal(AppConnection.Heroku),
oauthClientId: z.string().optional() methods: z.nativeEnum(HerokuConnectionMethod).array(),
}); oauthClientId: z.string().optional()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Heroku] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { HumanitecConnectionMethod } from "./humanitec-connection-enums"; import { HumanitecConnectionMethod } from "./humanitec-connection-enums";
export const HumanitecConnectionAccessTokenCredentialsSchema = z.object({ export const HumanitecConnectionAccessTokenCredentialsSchema = z.object({
@@ -25,7 +26,7 @@ export const SanitizedHumanitecConnectionSchema = z.discriminatedUnion("method",
BaseHumanitecConnectionSchema.extend({ BaseHumanitecConnectionSchema.extend({
method: z.literal(HumanitecConnectionMethod.ApiToken), method: z.literal(HumanitecConnectionMethod.ApiToken),
credentials: HumanitecConnectionAccessTokenCredentialsSchema.pick({}) credentials: HumanitecConnectionAccessTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Humanitec]} (API Token)` }))
]); ]);
export const ValidateHumanitecConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateHumanitecConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -51,8 +52,10 @@ export const UpdateHumanitecConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Humanitec)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Humanitec));
export const HumanitecConnectionListItemSchema = z.object({ export const HumanitecConnectionListItemSchema = z
name: z.literal("Humanitec"), .object({
app: z.literal(AppConnection.Humanitec), name: z.literal("Humanitec"),
methods: z.nativeEnum(HumanitecConnectionMethod).array() app: z.literal(AppConnection.Humanitec),
}); methods: z.nativeEnum(HumanitecConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Humanitec] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { LaravelForgeConnectionMethod } from "./laravel-forge-connection-enums"; import { LaravelForgeConnectionMethod } from "./laravel-forge-connection-enums";
export const LaravelForgeConnectionApiTokenCredentialsSchema = z.object({ export const LaravelForgeConnectionApiTokenCredentialsSchema = z.object({
@@ -25,7 +26,7 @@ export const SanitizedLaravelForgeConnectionSchema = z.discriminatedUnion("metho
BaseLaravelForgeConnectionSchema.extend({ BaseLaravelForgeConnectionSchema.extend({
method: z.literal(LaravelForgeConnectionMethod.ApiToken), method: z.literal(LaravelForgeConnectionMethod.ApiToken),
credentials: LaravelForgeConnectionApiTokenCredentialsSchema.pick({}) credentials: LaravelForgeConnectionApiTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.LaravelForge]} (API Token)` }))
]); ]);
export const ValidateLaravelForgeConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateLaravelForgeConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -51,8 +52,10 @@ export const UpdateLaravelForgeConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.LaravelForge)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.LaravelForge));
export const LaravelForgeConnectionListItemSchema = z.object({ export const LaravelForgeConnectionListItemSchema = z
name: z.literal("Laravel Forge"), .object({
app: z.literal(AppConnection.LaravelForge), name: z.literal("Laravel Forge"),
methods: z.nativeEnum(LaravelForgeConnectionMethod).array() app: z.literal(AppConnection.LaravelForge),
}); methods: z.nativeEnum(LaravelForgeConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.LaravelForge] }));
@@ -1,6 +1,11 @@
import ldap from "ldapjs"; 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 { 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 { logger } from "@app/lib/logger";
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator"; import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
import { AppConnection } from "@app/services/app-connection/app-connection-enums"; 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 { LdapConnectionMethod } from "./ldap-connection-enums";
import { TLdapConnectionConfig } from "./ldap-connection-types"; 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 = () => { export const getLdapConnectionListItem = () => {
return { return {
name: "LDAP" as const, name: "LDAP" as const,
@@ -16,8 +81,6 @@ export const getLdapConnectionListItem = () => {
}; };
}; };
const LDAP_TIMEOUT = 15_000;
export const getLdapConnectionClient = async ({ export const getLdapConnectionClient = async ({
url, url,
dn, dn,
@@ -25,78 +88,112 @@ export const getLdapConnectionClient = async ({
sslCertificate, sslCertificate,
sslRejectUnauthorized = true sslRejectUnauthorized = true
}: TLdapConnectionConfig["credentials"]) => { }: TLdapConnectionConfig["credentials"]) => {
await blockLocalAndPrivateIpAddresses(url); await blockLocalAndPrivateIpAddresses(url, false);
const isSSL = url.startsWith("ldaps"); const isSSL = url.startsWith("ldaps");
return new Promise<ldap.Client>((resolve, reject) => { const client = ldap.createClient({
const client = ldap.createClient({ url,
url, timeout: LDAP_TIMEOUT,
timeout: LDAP_TIMEOUT, connectTimeout: LDAP_TIMEOUT,
connectTimeout: LDAP_TIMEOUT, tlsOptions: isSSL
tlsOptions: isSSL ? {
? { rejectUnauthorized: sslRejectUnauthorized,
rejectUnauthorized: sslRejectUnauthorized, ca: sslCertificate ? [sslCertificate] : undefined
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();
} }
: undefined
resolve(client);
});
});
}); });
return setupLdapClientHandlers<ldap.Client>(client, dn, password, (ldapClient) => ldapClient);
}; };
export const validateLdapConnectionCredentials = async ({ credentials }: TLdapConnectionConfig) => { export const executeWithPotentialGateway = async <T>(
let client: ldap.Client | undefined; 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 { if (gatewayId && gatewayV2Service) {
client = await getLdapConnectionClient(credentials); 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 (!platformConnectionDetails) {
if (!client.connected) { throw new BadRequestError({ message: "Unable to connect to gateway, no platform connection details found" });
throw new BadRequestError({ message: "Unable to connect to LDAP server" });
} }
return credentials; return withGatewayV2Proxy(
} catch (e: unknown) { async (proxyPort) => {
throw new BadRequestError({ const proxyUrl = constructLdapUrl(protocol, "localhost", proxyPort);
message: `Unable to validate connection: ${(e as Error).message || "verify credentials"}` 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 { } 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"
}`
});
} }
}; };
@@ -9,6 +9,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { LdapConnectionMethod, LdapProvider } from "./ldap-connection-enums"; import { LdapConnectionMethod, LdapProvider } from "./ldap-connection-enums";
export const LdapConnectionSimpleBindCredentialsSchema = z.object({ export const LdapConnectionSimpleBindCredentialsSchema = z.object({
@@ -61,7 +62,7 @@ export const SanitizedLdapConnectionSchema = z.discriminatedUnion("method", [
sslRejectUnauthorized: true, sslRejectUnauthorized: true,
sslCertificate: true sslCertificate: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.LDAP]} (Simple Bind)` }))
]); ]);
export const ValidateLdapConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateLdapConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -74,7 +75,9 @@ export const ValidateLdapConnectionCredentialsSchema = z.discriminatedUnion("met
]); ]);
export const CreateLdapConnectionSchema = ValidateLdapConnectionCredentialsSchema.and( export const CreateLdapConnectionSchema = ValidateLdapConnectionCredentialsSchema.and(
GenericCreateAppConnectionFieldsSchema(AppConnection.LDAP) GenericCreateAppConnectionFieldsSchema(AppConnection.LDAP, {
supportsGateways: true
})
); );
export const UpdateLdapConnectionSchema = z export const UpdateLdapConnectionSchema = z
@@ -83,12 +86,18 @@ export const UpdateLdapConnectionSchema = z
AppConnections.UPDATE(AppConnection.LDAP).credentials AppConnections.UPDATE(AppConnection.LDAP).credentials
) )
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.LDAP)); .and(
GenericUpdateAppConnectionFieldsSchema(AppConnection.LDAP, {
supportsGateways: true
})
);
export const LdapConnectionListItemSchema = z.object({ export const LdapConnectionListItemSchema = z
name: z.literal("LDAP"), .object({
app: z.literal(AppConnection.LDAP), name: z.literal("LDAP"),
// the below is preferable but currently breaks with our zod to json schema parser app: z.literal(AppConnection.LDAP),
// methods: z.tuple([z.literal(AwsConnectionMethod.ServicePrincipal), z.literal(AwsConnectionMethod.AccessKey)]), // the below is preferable but currently breaks with our zod to json schema parser
methods: z.nativeEnum(LdapConnectionMethod).array() // 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] }));
@@ -17,6 +17,9 @@ export type TLdapConnectionInput = z.infer<typeof CreateLdapConnectionSchema> &
export type TValidateLdapConnectionCredentialsSchema = typeof ValidateLdapConnectionCredentialsSchema; export type TValidateLdapConnectionCredentialsSchema = typeof ValidateLdapConnectionCredentialsSchema;
export type TLdapConnectionConfig = DiscriminativePick<TLdapConnection, "method" | "app" | "credentials"> & { export type TLdapConnectionConfig = DiscriminativePick<
TLdapConnectionInput,
"method" | "app" | "credentials" | "gatewayId"
> & {
orgId: string; orgId: string;
}; };
@@ -8,6 +8,7 @@ import {
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { AppConnection } from "../app-connection-enums"; import { AppConnection } from "../app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql"; import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql";
import { MsSqlConnectionMethod } from "./mssql-connection-enums"; import { MsSqlConnectionMethod } from "./mssql-connection-enums";
@@ -34,7 +35,7 @@ export const SanitizedMsSqlConnectionSchema = z.discriminatedUnion("method", [
sslRejectUnauthorized: true, sslRejectUnauthorized: true,
sslCertificate: true sslCertificate: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.MsSql]} (Username and Password)` }))
]); ]);
export const ValidateMsSqlConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateMsSqlConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -68,9 +69,11 @@ export const UpdateMsSqlConnectionSchema = z
}) })
); );
export const MsSqlConnectionListItemSchema = z.object({ export const MsSqlConnectionListItemSchema = z
name: z.literal("Microsoft SQL Server"), .object({
app: z.literal(AppConnection.MsSql), name: z.literal("Microsoft SQL Server"),
methods: z.nativeEnum(MsSqlConnectionMethod).array(), app: z.literal(AppConnection.MsSql),
supportsPlatformManagement: z.literal(true) methods: z.nativeEnum(MsSqlConnectionMethod).array(),
}); supportsPlatformManagement: z.literal(true)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.MsSql] }));
@@ -8,6 +8,7 @@ import {
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { AppConnection } from "../app-connection-enums"; import { AppConnection } from "../app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql"; import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql";
import { MySqlConnectionMethod } from "./mysql-connection-enums"; import { MySqlConnectionMethod } from "./mysql-connection-enums";
@@ -32,7 +33,7 @@ export const SanitizedMySqlConnectionSchema = z.discriminatedUnion("method", [
sslRejectUnauthorized: true, sslRejectUnauthorized: true,
sslCertificate: true sslCertificate: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.MySql]} (Username and Password)` }))
]); ]);
export const ValidateMySqlConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateMySqlConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -66,9 +67,11 @@ export const UpdateMySqlConnectionSchema = z
}) })
); );
export const MySqlConnectionListItemSchema = z.object({ export const MySqlConnectionListItemSchema = z
name: z.literal("MySQL"), .object({
app: z.literal(AppConnection.MySql), name: z.literal("MySQL"),
methods: z.nativeEnum(MySqlConnectionMethod).array(), app: z.literal(AppConnection.MySql),
supportsPlatformManagement: z.literal(true) methods: z.nativeEnum(MySqlConnectionMethod).array(),
}); supportsPlatformManagement: z.literal(true)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.MySql] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { NetlifyConnectionMethod } from "./netlify-connection-constants"; import { NetlifyConnectionMethod } from "./netlify-connection-constants";
export const NetlifyConnectionMethodSchema = z export const NetlifyConnectionMethodSchema = z
@@ -36,7 +37,7 @@ export const SanitizedNetlifyConnectionSchema = z.discriminatedUnion("method", [
BaseNetlifyConnectionSchema.extend({ BaseNetlifyConnectionSchema.extend({
method: NetlifyConnectionMethodSchema, method: NetlifyConnectionMethodSchema,
credentials: NetlifyConnectionAccessTokenCredentialsSchema.pick({}) credentials: NetlifyConnectionAccessTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Netlify]} (Access Token)` }))
]); ]);
export const ValidateNetlifyConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateNetlifyConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -60,8 +61,10 @@ export const UpdateNetlifyConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Netlify)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Netlify));
export const NetlifyConnectionListItemSchema = z.object({ export const NetlifyConnectionListItemSchema = z
name: z.literal("Netlify"), .object({
app: z.literal(AppConnection.Netlify), name: z.literal("Netlify"),
methods: z.nativeEnum(NetlifyConnectionMethod).array() app: z.literal(AppConnection.Netlify),
}); methods: z.nativeEnum(NetlifyConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Netlify] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { NorthflankConnectionMethod } from "./northflank-connection-enums"; import { NorthflankConnectionMethod } from "./northflank-connection-enums";
export const NorthflankConnectionApiTokenCredentialsSchema = z.object({ export const NorthflankConnectionApiTokenCredentialsSchema = z.object({
@@ -27,7 +28,7 @@ export const SanitizedNorthflankConnectionSchema = z.discriminatedUnion("method"
BaseNorthflankConnectionSchema.extend({ BaseNorthflankConnectionSchema.extend({
method: z.literal(NorthflankConnectionMethod.ApiToken), method: z.literal(NorthflankConnectionMethod.ApiToken),
credentials: NorthflankConnectionApiTokenCredentialsSchema.pick({}) credentials: NorthflankConnectionApiTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Northflank]} (API Token)` }))
]); ]);
export const ValidateNorthflankConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateNorthflankConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -53,8 +54,10 @@ export const UpdateNorthflankConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Northflank)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Northflank));
export const NorthflankConnectionListItemSchema = z.object({ export const NorthflankConnectionListItemSchema = z
name: z.literal("Northflank"), .object({
app: z.literal(AppConnection.Northflank), name: z.literal("Northflank"),
methods: z.nativeEnum(NorthflankConnectionMethod).array() app: z.literal(AppConnection.Northflank),
}); methods: z.nativeEnum(NorthflankConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Northflank] }));
@@ -9,6 +9,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { OktaConnectionMethod } from "./okta-connection-enums"; import { OktaConnectionMethod } from "./okta-connection-enums";
export const OktaConnectionApiTokenCredentialsSchema = z.object({ export const OktaConnectionApiTokenCredentialsSchema = z.object({
@@ -40,7 +41,7 @@ export const SanitizedOktaConnectionSchema = z.discriminatedUnion("method", [
credentials: OktaConnectionApiTokenCredentialsSchema.pick({ credentials: OktaConnectionApiTokenCredentialsSchema.pick({
instanceUrl: true instanceUrl: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Okta]} (API Token)` }))
]); ]);
export const ValidateOktaConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateOktaConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -62,8 +63,10 @@ export const UpdateOktaConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Okta)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Okta));
export const OktaConnectionListItemSchema = z.object({ export const OktaConnectionListItemSchema = z
name: z.literal("Okta"), .object({
app: z.literal(AppConnection.Okta), name: z.literal("Okta"),
methods: z.nativeEnum(OktaConnectionMethod).array() app: z.literal(AppConnection.Okta),
}); methods: z.nativeEnum(OktaConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Okta] }));
@@ -8,6 +8,7 @@ import {
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { AppConnection } from "../app-connection-enums"; import { AppConnection } from "../app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql"; import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql";
import { PostgresConnectionMethod } from "./postgres-connection-enums"; import { PostgresConnectionMethod } from "./postgres-connection-enums";
@@ -32,7 +33,7 @@ export const SanitizedPostgresConnectionSchema = z.discriminatedUnion("method",
sslRejectUnauthorized: true, sslRejectUnauthorized: true,
sslCertificate: true sslCertificate: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Postgres]} (Username and Password)` }))
]); ]);
export const ValidatePostgresConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidatePostgresConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -66,9 +67,11 @@ export const UpdatePostgresConnectionSchema = z
}) })
); );
export const PostgresConnectionListItemSchema = z.object({ export const PostgresConnectionListItemSchema = z
name: z.literal("PostgreSQL"), .object({
app: z.literal(AppConnection.Postgres), name: z.literal("PostgreSQL"),
methods: z.nativeEnum(PostgresConnectionMethod).array(), app: z.literal(AppConnection.Postgres),
supportsPlatformManagement: z.literal(true) methods: z.nativeEnum(PostgresConnectionMethod).array(),
}); supportsPlatformManagement: z.literal(true)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Postgres] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { RailwayConnectionMethod } from "./railway-connection-constants"; import { RailwayConnectionMethod } from "./railway-connection-constants";
export const RailwayConnectionMethodSchema = z export const RailwayConnectionMethodSchema = z
@@ -36,7 +37,7 @@ export const SanitizedRailwayConnectionSchema = z.discriminatedUnion("method", [
BaseRailwayConnectionSchema.extend({ BaseRailwayConnectionSchema.extend({
method: RailwayConnectionMethodSchema, method: RailwayConnectionMethodSchema,
credentials: RailwayConnectionAccessTokenCredentialsSchema.pick({}) credentials: RailwayConnectionAccessTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Railway]} (Access Token)` }))
]); ]);
export const ValidateRailwayConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateRailwayConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -60,11 +61,13 @@ export const UpdateRailwayConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Railway)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Railway));
export const RailwayConnectionListItemSchema = z.object({ export const RailwayConnectionListItemSchema = z
name: z.literal("Railway"), .object({
app: z.literal(AppConnection.Railway), name: z.literal("Railway"),
methods: z.nativeEnum(RailwayConnectionMethod).array() 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({ export const RailwayResourceSchema = z.object({
node: z.object({ node: z.object({
@@ -8,6 +8,7 @@ import {
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { AppConnection } from "../app-connection-enums"; import { AppConnection } from "../app-connection-enums";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { RedisConnectionMethod } from "./redis-connection-enums"; import { RedisConnectionMethod } from "./redis-connection-enums";
export const BaseRedisUsernameAndPasswordConnectionSchema = z.object({ export const BaseRedisUsernameAndPasswordConnectionSchema = z.object({
@@ -45,7 +46,7 @@ export const SanitizedRedisConnectionSchema = z.discriminatedUnion("method", [
sslRejectUnauthorized: true, sslRejectUnauthorized: true,
sslCertificate: true sslCertificate: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Redis]} (Username and Password)` }))
]); ]);
export const ValidateRedisConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateRedisConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -79,9 +80,11 @@ export const UpdateRedisConnectionSchema = z
}) })
); );
export const RedisConnectionListItemSchema = z.object({ export const RedisConnectionListItemSchema = z
name: z.literal("Redis"), .object({
app: z.literal(AppConnection.Redis), name: z.literal("Redis"),
methods: z.nativeEnum(RedisConnectionMethod).array(), app: z.literal(AppConnection.Redis),
supportsPlatformManagement: z.literal(false) methods: z.nativeEnum(RedisConnectionMethod).array(),
}); supportsPlatformManagement: z.literal(false)
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Redis] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { RenderConnectionMethod } from "./render-connection-enums"; import { RenderConnectionMethod } from "./render-connection-enums";
export const RenderConnectionApiKeyCredentialsSchema = z.object({ export const RenderConnectionApiKeyCredentialsSchema = z.object({
@@ -25,7 +26,7 @@ export const SanitizedRenderConnectionSchema = z.discriminatedUnion("method", [
BaseRenderConnectionSchema.extend({ BaseRenderConnectionSchema.extend({
method: z.literal(RenderConnectionMethod.ApiKey), method: z.literal(RenderConnectionMethod.ApiKey),
credentials: RenderConnectionApiKeyCredentialsSchema.pick({}) credentials: RenderConnectionApiKeyCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Render]} (API Key)` }))
]); ]);
export const ValidateRenderConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateRenderConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -49,8 +50,10 @@ export const UpdateRenderConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Render)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Render));
export const RenderConnectionListItemSchema = z.object({ export const RenderConnectionListItemSchema = z
name: z.literal("Render"), .object({
app: z.literal(AppConnection.Render), name: z.literal("Render"),
methods: z.nativeEnum(RenderConnectionMethod).array() app: z.literal(AppConnection.Render),
}); methods: z.nativeEnum(RenderConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Render] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { SupabaseConnectionMethod } from "./supabase-connection-constants"; import { SupabaseConnectionMethod } from "./supabase-connection-constants";
export const SupabaseConnectionMethodSchema = z export const SupabaseConnectionMethodSchema = z
@@ -39,7 +40,7 @@ export const SanitizedSupabaseConnectionSchema = z.discriminatedUnion("method",
credentials: SupabaseConnectionAccessTokenCredentialsSchema.pick({ credentials: SupabaseConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true instanceUrl: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Supabase]} (Access Token)` }))
]); ]);
export const ValidateSupabaseConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateSupabaseConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -63,8 +64,10 @@ export const UpdateSupabaseConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Supabase)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Supabase));
export const SupabaseConnectionListItemSchema = z.object({ export const SupabaseConnectionListItemSchema = z
name: z.literal("Supabase"), .object({
app: z.literal(AppConnection.Supabase), name: z.literal("Supabase"),
methods: z.nativeEnum(SupabaseConnectionMethod).array() app: z.literal(AppConnection.Supabase),
}); methods: z.nativeEnum(SupabaseConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Supabase] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { TeamCityConnectionMethod } from "./teamcity-connection-enums"; import { TeamCityConnectionMethod } from "./teamcity-connection-enums";
export const TeamCityConnectionAccessTokenCredentialsSchema = z.object({ export const TeamCityConnectionAccessTokenCredentialsSchema = z.object({
@@ -37,7 +38,7 @@ export const SanitizedTeamCityConnectionSchema = z.discriminatedUnion("method",
credentials: TeamCityConnectionAccessTokenCredentialsSchema.pick({ credentials: TeamCityConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true instanceUrl: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.TeamCity]} (Access Token)` }))
]); ]);
export const ValidateTeamCityConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateTeamCityConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -63,8 +64,10 @@ export const UpdateTeamCityConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.TeamCity)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.TeamCity));
export const TeamCityConnectionListItemSchema = z.object({ export const TeamCityConnectionListItemSchema = z
name: z.literal("TeamCity"), .object({
app: z.literal(AppConnection.TeamCity), name: z.literal("TeamCity"),
methods: z.nativeEnum(TeamCityConnectionMethod).array() app: z.literal(AppConnection.TeamCity),
}); methods: z.nativeEnum(TeamCityConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.TeamCity] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { TerraformCloudConnectionMethod } from "./terraform-cloud-connection-enums"; import { TerraformCloudConnectionMethod } from "./terraform-cloud-connection-enums";
export const TerraformCloudConnectionAccessTokenCredentialsSchema = z.object({ export const TerraformCloudConnectionAccessTokenCredentialsSchema = z.object({
@@ -27,7 +28,7 @@ export const SanitizedTerraformCloudConnectionSchema = z.discriminatedUnion("met
BaseTerraformCloudConnectionSchema.extend({ BaseTerraformCloudConnectionSchema.extend({
method: z.literal(TerraformCloudConnectionMethod.ApiToken), method: z.literal(TerraformCloudConnectionMethod.ApiToken),
credentials: TerraformCloudConnectionAccessTokenCredentialsSchema.pick({}) credentials: TerraformCloudConnectionAccessTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.TerraformCloud]} (API Token)` }))
]); ]);
export const ValidateTerraformCloudConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateTerraformCloudConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -53,8 +54,10 @@ export const UpdateTerraformCloudConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.TerraformCloud)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.TerraformCloud));
export const TerraformCloudConnectionListItemSchema = z.object({ export const TerraformCloudConnectionListItemSchema = z
name: z.literal("Terraform Cloud"), .object({
app: z.literal(AppConnection.TerraformCloud), name: z.literal("Terraform Cloud"),
methods: z.nativeEnum(TerraformCloudConnectionMethod).array() app: z.literal(AppConnection.TerraformCloud),
}); methods: z.nativeEnum(TerraformCloudConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.TerraformCloud] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { VercelConnectionMethod } from "./vercel-connection-enums"; import { VercelConnectionMethod } from "./vercel-connection-enums";
export const VercelConnectionAccessTokenCredentialsSchema = z.object({ export const VercelConnectionAccessTokenCredentialsSchema = z.object({
@@ -27,7 +28,7 @@ export const SanitizedVercelConnectionSchema = z.discriminatedUnion("method", [
BaseVercelConnectionSchema.extend({ BaseVercelConnectionSchema.extend({
method: z.literal(VercelConnectionMethod.ApiToken), method: z.literal(VercelConnectionMethod.ApiToken),
credentials: VercelConnectionAccessTokenCredentialsSchema.pick({}) credentials: VercelConnectionAccessTokenCredentialsSchema.pick({})
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Vercel]} (API Token)` }))
]); ]);
export const ValidateVercelConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateVercelConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -51,8 +52,10 @@ export const UpdateVercelConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Vercel)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Vercel));
export const VercelConnectionListItemSchema = z.object({ export const VercelConnectionListItemSchema = z
name: z.literal("Vercel"), .object({
app: z.literal(AppConnection.Vercel), name: z.literal("Vercel"),
methods: z.nativeEnum(VercelConnectionMethod).array() app: z.literal(AppConnection.Vercel),
}); methods: z.nativeEnum(VercelConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Vercel] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { WindmillConnectionMethod } from "./windmill-connection-enums"; import { WindmillConnectionMethod } from "./windmill-connection-enums";
export const WindmillConnectionAccessTokenCredentialsSchema = z.object({ export const WindmillConnectionAccessTokenCredentialsSchema = z.object({
@@ -37,7 +38,7 @@ export const SanitizedWindmillConnectionSchema = z.discriminatedUnion("method",
credentials: WindmillConnectionAccessTokenCredentialsSchema.pick({ credentials: WindmillConnectionAccessTokenCredentialsSchema.pick({
instanceUrl: true instanceUrl: true
}) })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Windmill]} (Access Token)` }))
]); ]);
export const ValidateWindmillConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateWindmillConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -63,8 +64,10 @@ export const UpdateWindmillConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Windmill)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Windmill));
export const WindmillConnectionListItemSchema = z.object({ export const WindmillConnectionListItemSchema = z
name: z.literal("Windmill"), .object({
app: z.literal(AppConnection.Windmill), name: z.literal("Windmill"),
methods: z.nativeEnum(WindmillConnectionMethod).array() app: z.literal(AppConnection.Windmill),
}); methods: z.nativeEnum(WindmillConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Windmill] }));
@@ -8,6 +8,7 @@ import {
GenericUpdateAppConnectionFieldsSchema GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas"; } from "@app/services/app-connection/app-connection-schemas";
import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps";
import { ZabbixConnectionMethod } from "./zabbix-connection-enums"; import { ZabbixConnectionMethod } from "./zabbix-connection-enums";
export const ZabbixConnectionApiTokenCredentialsSchema = z.object({ export const ZabbixConnectionApiTokenCredentialsSchema = z.object({
@@ -31,7 +32,7 @@ export const SanitizedZabbixConnectionSchema = z.discriminatedUnion("method", [
BaseZabbixConnectionSchema.extend({ BaseZabbixConnectionSchema.extend({
method: z.literal(ZabbixConnectionMethod.ApiToken), method: z.literal(ZabbixConnectionMethod.ApiToken),
credentials: ZabbixConnectionApiTokenCredentialsSchema.pick({ instanceUrl: true }) credentials: ZabbixConnectionApiTokenCredentialsSchema.pick({ instanceUrl: true })
}) }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.Zabbix]} (API Token)` }))
]); ]);
export const ValidateZabbixConnectionCredentialsSchema = z.discriminatedUnion("method", [ export const ValidateZabbixConnectionCredentialsSchema = z.discriminatedUnion("method", [
@@ -55,8 +56,10 @@ export const UpdateZabbixConnectionSchema = z
}) })
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Zabbix)); .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Zabbix));
export const ZabbixConnectionListItemSchema = z.object({ export const ZabbixConnectionListItemSchema = z
name: z.literal("Zabbix"), .object({
app: z.literal(AppConnection.Zabbix), name: z.literal("Zabbix"),
methods: z.nativeEnum(ZabbixConnectionMethod).array() app: z.literal(AppConnection.Zabbix),
}); methods: z.nativeEnum(ZabbixConnectionMethod).array()
})
.describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.Zabbix] }));
@@ -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 { return {
tokens: { tokens: {
accessToken: token.access, 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 { return {
...tokens, ...tokens,
user, user,
@@ -1039,6 +1086,33 @@ export const authLoginServiceFactory = ({
organizationId 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; return { token, isMfaEnabled: false, user: userEnc, decodedProviderToken } as const;
}; };
@@ -1,7 +1,9 @@
import * as x509 from "@peculiar/x509"; import * as x509 from "@peculiar/x509";
import acme, { CsrBuffer } from "acme-client"; import acme, { CsrBuffer } from "acme-client";
import { Knex } from "knex";
import { TableName } from "@app/db/schemas"; import { TableName } from "@app/db/schemas";
import { getConfig } from "@app/lib/config/env";
import { crypto } from "@app/lib/crypto/cryptography"; import { crypto } from "@app/lib/crypto/cryptography";
import { BadRequestError, CryptographyError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, CryptographyError, NotFoundError } from "@app/lib/errors";
import { OrgServiceActor } from "@app/lib/types"; import { OrgServiceActor } from "@app/lib/types";
@@ -29,8 +31,6 @@ import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-ut
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
import { getConfig } from "@app/lib/config/env";
import { Knex } from "knex";
import { TCertificateAuthorityDALFactory } from "../certificate-authority-dal"; import { TCertificateAuthorityDALFactory } from "../certificate-authority-dal";
import { CaStatus, CaType } from "../certificate-authority-enums"; import { CaStatus, CaType } from "../certificate-authority-enums";
import { keyAlgorithmToAlgCfg } from "../certificate-authority-fns"; import { keyAlgorithmToAlgCfg } from "../certificate-authority-fns";
@@ -5,16 +5,16 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import type { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import type { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { ActorType, AuthMethod } from "../auth/auth-type"; import { ActorType, AuthMethod } from "../auth/auth-type";
import type { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal";
import type { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal";
import type { TCertificateAuthorityCertDALFactory } from "../certificate-authority/certificate-authority-cert-dal"; import type { TCertificateAuthorityCertDALFactory } from "../certificate-authority/certificate-authority-cert-dal";
import type { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal"; import type { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal";
import type { TCertificateTemplateV2DALFactory } from "../certificate-template-v2/certificate-template-v2-dal"; import type { TCertificateTemplateV2DALFactory } from "../certificate-template-v2/certificate-template-v2-dal";
import type { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal";
import type { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal";
import { TAcmeEnrollmentConfigDALFactory } from "../enrollment-config/acme-enrollment-config-dal"; import { TAcmeEnrollmentConfigDALFactory } from "../enrollment-config/acme-enrollment-config-dal";
import type { TApiEnrollmentConfigDALFactory } from "../enrollment-config/api-enrollment-config-dal"; import type { TApiEnrollmentConfigDALFactory } from "../enrollment-config/api-enrollment-config-dal";
import type { TEstEnrollmentConfigDALFactory } from "../enrollment-config/est-enrollment-config-dal"; import type { TEstEnrollmentConfigDALFactory } from "../enrollment-config/est-enrollment-config-dal";
@@ -2,6 +2,7 @@ import { ForbiddenError } from "@casl/ability";
import * as x509 from "@peculiar/x509"; import * as x509 from "@peculiar/x509";
import { ActionProjectType } from "@app/db/schemas"; import { ActionProjectType } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
import { import {
ProjectPermissionCertificateActions, ProjectPermissionCertificateActions,
@@ -14,14 +15,13 @@ import { getConfig } from "@app/lib/config/env";
import { crypto } from "@app/lib/crypto/cryptography"; import { crypto } from "@app/lib/crypto/cryptography";
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { ActorAuthMethod, ActorType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType } from "../auth/auth-type";
import { TCertificateAuthorityCertDALFactory } from "../certificate-authority/certificate-authority-cert-dal";
import { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal";
import { TCertificateTemplateV2DALFactory } from "../certificate-template-v2/certificate-template-v2-dal";
import { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal"; import { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal";
import { getCertificateCredentials, isCertChainValid } from "../certificate/certificate-fns"; import { getCertificateCredentials, isCertChainValid } from "../certificate/certificate-fns";
import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal"; import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal";
import { TCertificateAuthorityCertDALFactory } from "../certificate-authority/certificate-authority-cert-dal";
import { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal";
import { TCertificateTemplateV2DALFactory } from "../certificate-template-v2/certificate-template-v2-dal";
import { TAcmeEnrollmentConfigDALFactory } from "../enrollment-config/acme-enrollment-config-dal"; import { TAcmeEnrollmentConfigDALFactory } from "../enrollment-config/acme-enrollment-config-dal";
import { TApiEnrollmentConfigDALFactory } from "../enrollment-config/api-enrollment-config-dal"; import { TApiEnrollmentConfigDALFactory } from "../enrollment-config/api-enrollment-config-dal";
import { TAcmeConfigData, TApiConfigData, TEstConfigData } from "../enrollment-config/enrollment-config-types"; import { TAcmeConfigData, TApiConfigData, TEstConfigData } from "../enrollment-config/enrollment-config-types";
+21 -1
View File
@@ -6,6 +6,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars"; import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
import { UnpackedPermissionSchema, unpackPermissions } from "@app/server/routes/sanitizedSchema/permission"; 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 { ActorType } from "../auth/auth-type";
import { TExternalGroupOrgRoleMappingDALFactory } from "../external-group-org-role-mapping/external-group-org-role-mapping-dal"; 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">; permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
projectDAL: Pick<TProjectDALFactory, "findById">; projectDAL: Pick<TProjectDALFactory, "findById">;
externalGroupOrgRoleMappingDAL: Pick<TExternalGroupOrgRoleMappingDALFactory, "findOne">; externalGroupOrgRoleMappingDAL: Pick<TExternalGroupOrgRoleMappingDALFactory, "findOne">;
membershipRoleDAL: Pick<TMembershipRoleDALFactory, "find">;
}; };
export type TRoleServiceFactory = ReturnType<typeof roleServiceFactory>; export type TRoleServiceFactory = ReturnType<typeof roleServiceFactory>;
@@ -43,7 +45,8 @@ export const roleServiceFactory = ({
projectDAL, projectDAL,
identityDAL, identityDAL,
userDAL, userDAL,
externalGroupOrgRoleMappingDAL externalGroupOrgRoleMappingDAL,
membershipRoleDAL
}: TRoleServiceFactoryDep) => { }: TRoleServiceFactoryDep) => {
const orgRoleFactory = newOrgRoleFactory({ const orgRoleFactory = newOrgRoleFactory({
permissionService, permissionService,
@@ -137,6 +140,23 @@ export const roleServiceFactory = ({
}); });
if (!existingRole) throw new NotFoundError({ message: `Role with ${dto.selector.id} not found` }); 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({ const [role] = await roleDAL.delete({
id: existingRole.id, id: existingRole.id,
[scope.key]: scope.value [scope.key]: scope.value
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const OnePassSyncDestinationConfigSchema = z.object({ const OnePassSyncDestinationConfigSchema = z.object({
vaultId: z.string().trim().min(1, "Vault required").describe(SecretSyncs.DESTINATION_CONFIG.ONEPASS.vaultId), 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) valueLabel: z.string().trim().optional().describe(SecretSyncs.DESTINATION_CONFIG.ONEPASS.valueLabel)
@@ -17,10 +19,12 @@ const OnePassSyncDestinationConfigSchema = z.object({
const OnePassSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const OnePassSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const OnePassSyncSchema = BaseSecretSyncSchema(SecretSync.OnePass, OnePassSyncOptionsConfig).extend({ export const OnePassSyncSchema = BaseSecretSyncSchema(SecretSync.OnePass, OnePassSyncOptionsConfig)
destination: z.literal(SecretSync.OnePass), .extend({
destinationConfig: OnePassSyncDestinationConfigSchema destination: z.literal(SecretSync.OnePass),
}); destinationConfig: OnePassSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OnePass] }));
export const CreateOnePassSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateOnePassSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.OnePass, SecretSync.OnePass,
@@ -36,9 +40,11 @@ export const UpdateOnePassSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: OnePassSyncDestinationConfigSchema.optional() destinationConfig: OnePassSyncDestinationConfigSchema.optional()
}); });
export const OnePassSyncListItemSchema = z.object({ export const OnePassSyncListItemSchema = z
name: z.literal("1Password"), .object({
connection: z.literal(AppConnection.OnePass), name: z.literal("1Password"),
destination: z.literal(SecretSync.OnePass), connection: z.literal(AppConnection.OnePass),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.OnePass),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OnePass] }));
@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const tagFieldCharacterValidator = characterValidator([ const tagFieldCharacterValidator = characterValidator([
CharacterType.AlphaNumeric, CharacterType.AlphaNumeric,
CharacterType.Spaces, CharacterType.Spaces,
@@ -105,10 +107,12 @@ export const AwsParameterStoreSyncSchema = BaseSecretSyncSchema(
SecretSync.AWSParameterStore, SecretSync.AWSParameterStore,
AwsParameterStoreSyncOptionsConfig, AwsParameterStoreSyncOptionsConfig,
AwsParameterStoreSyncOptionsSchema AwsParameterStoreSyncOptionsSchema
).extend({ )
destination: z.literal(SecretSync.AWSParameterStore), .extend({
destinationConfig: AwsParameterStoreSyncDestinationConfigSchema destination: z.literal(SecretSync.AWSParameterStore),
}); destinationConfig: AwsParameterStoreSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AWSParameterStore] }));
export const CreateAwsParameterStoreSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateAwsParameterStoreSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AWSParameterStore, SecretSync.AWSParameterStore,
@@ -126,9 +130,11 @@ export const UpdateAwsParameterStoreSyncSchema = GenericUpdateSecretSyncFieldsSc
destinationConfig: AwsParameterStoreSyncDestinationConfigSchema.optional() destinationConfig: AwsParameterStoreSyncDestinationConfigSchema.optional()
}); });
export const AwsParameterStoreSyncListItemSchema = z.object({ export const AwsParameterStoreSyncListItemSchema = z
name: z.literal("AWS Parameter Store"), .object({
connection: z.literal(AppConnection.AWS), name: z.literal("AWS Parameter Store"),
destination: z.literal(SecretSync.AWSParameterStore), connection: z.literal(AppConnection.AWS),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.AWSParameterStore),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AWSParameterStore] }));
@@ -12,6 +12,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const AwsSecretsManagerSyncDestinationConfigSchema = z const AwsSecretsManagerSyncDestinationConfigSchema = z
.discriminatedUnion("mappingBehavior", [ .discriminatedUnion("mappingBehavior", [
z.object({ z.object({
@@ -119,10 +121,12 @@ export const AwsSecretsManagerSyncSchema = BaseSecretSyncSchema(
SecretSync.AWSSecretsManager, SecretSync.AWSSecretsManager,
AwsSecretsManagerSyncOptionsConfig, AwsSecretsManagerSyncOptionsConfig,
AwsSecretsManagerSyncOptionsSchema AwsSecretsManagerSyncOptionsSchema
).extend({ )
destination: z.literal(SecretSync.AWSSecretsManager), .extend({
destinationConfig: AwsSecretsManagerSyncDestinationConfigSchema destination: z.literal(SecretSync.AWSSecretsManager),
}); destinationConfig: AwsSecretsManagerSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AWSSecretsManager] }));
export const CreateAwsSecretsManagerSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateAwsSecretsManagerSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AWSSecretsManager, SecretSync.AWSSecretsManager,
@@ -164,9 +168,11 @@ export const UpdateAwsSecretsManagerSyncSchema = GenericUpdateSecretSyncFieldsSc
} }
}); });
export const AwsSecretsManagerSyncListItemSchema = z.object({ export const AwsSecretsManagerSyncListItemSchema = z
name: z.literal("AWS Secrets Manager"), .object({
connection: z.literal(AppConnection.AWS), name: z.literal("AWS Secrets Manager"),
destination: z.literal(SecretSync.AWSSecretsManager), connection: z.literal(AppConnection.AWS),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.AWSSecretsManager),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AWSSecretsManager] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const AzureAppConfigurationSyncDestinationConfigSchema = z.object({ const AzureAppConfigurationSyncDestinationConfigSchema = z.object({
configurationUrl: z configurationUrl: z
.string() .string()
@@ -23,10 +25,12 @@ const AzureAppConfigurationSyncOptionsConfig: TSyncOptionsConfig = { canImportSe
export const AzureAppConfigurationSyncSchema = BaseSecretSyncSchema( export const AzureAppConfigurationSyncSchema = BaseSecretSyncSchema(
SecretSync.AzureAppConfiguration, SecretSync.AzureAppConfiguration,
AzureAppConfigurationSyncOptionsConfig AzureAppConfigurationSyncOptionsConfig
).extend({ )
destination: z.literal(SecretSync.AzureAppConfiguration), .extend({
destinationConfig: AzureAppConfigurationSyncDestinationConfigSchema destination: z.literal(SecretSync.AzureAppConfiguration),
}); destinationConfig: AzureAppConfigurationSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureAppConfiguration] }));
export const CreateAzureAppConfigurationSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateAzureAppConfigurationSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AzureAppConfiguration, SecretSync.AzureAppConfiguration,
@@ -42,9 +46,11 @@ export const UpdateAzureAppConfigurationSyncSchema = GenericUpdateSecretSyncFiel
destinationConfig: AzureAppConfigurationSyncDestinationConfigSchema.optional() destinationConfig: AzureAppConfigurationSyncDestinationConfigSchema.optional()
}); });
export const AzureAppConfigurationSyncListItemSchema = z.object({ export const AzureAppConfigurationSyncListItemSchema = z
name: z.literal("Azure App Configuration"), .object({
connection: z.literal(AppConnection.AzureAppConfiguration), name: z.literal("Azure App Configuration"),
destination: z.literal(SecretSync.AzureAppConfiguration), connection: z.literal(AppConnection.AzureAppConfiguration),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.AzureAppConfiguration),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureAppConfiguration] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
export const AzureDevOpsSyncDestinationConfigSchema = z.object({ export const AzureDevOpsSyncDestinationConfigSchema = z.object({
devopsProjectId: z devopsProjectId: z
.string() .string()
@@ -23,10 +25,12 @@ export const AzureDevOpsSyncDestinationConfigSchema = z.object({
const AzureDevOpsSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; const AzureDevOpsSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const AzureDevOpsSyncSchema = BaseSecretSyncSchema(SecretSync.AzureDevOps, AzureDevOpsSyncOptionsConfig).extend({ export const AzureDevOpsSyncSchema = BaseSecretSyncSchema(SecretSync.AzureDevOps, AzureDevOpsSyncOptionsConfig)
destination: z.literal(SecretSync.AzureDevOps), .extend({
destinationConfig: AzureDevOpsSyncDestinationConfigSchema destination: z.literal(SecretSync.AzureDevOps),
}); destinationConfig: AzureDevOpsSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureDevOps] }));
export const CreateAzureDevOpsSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateAzureDevOpsSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AzureDevOps, SecretSync.AzureDevOps,
@@ -42,9 +46,11 @@ export const UpdateAzureDevOpsSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: AzureDevOpsSyncDestinationConfigSchema.optional() destinationConfig: AzureDevOpsSyncDestinationConfigSchema.optional()
}); });
export const AzureDevOpsSyncListItemSchema = z.object({ export const AzureDevOpsSyncListItemSchema = z
name: z.literal("Azure DevOps"), .object({
connection: z.literal(AppConnection.AzureDevOps), name: z.literal("Azure DevOps"),
destination: z.literal(SecretSync.AzureDevOps), connection: z.literal(AppConnection.AzureDevOps),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.AzureDevOps),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureDevOps] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const AzureKeyVaultSyncDestinationConfigSchema = z.object({ const AzureKeyVaultSyncDestinationConfigSchema = z.object({
vaultBaseUrl: z vaultBaseUrl: z
.string() .string()
@@ -20,13 +22,12 @@ const AzureKeyVaultSyncDestinationConfigSchema = z.object({
const AzureKeyVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const AzureKeyVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const AzureKeyVaultSyncSchema = BaseSecretSyncSchema( export const AzureKeyVaultSyncSchema = BaseSecretSyncSchema(SecretSync.AzureKeyVault, AzureKeyVaultSyncOptionsConfig)
SecretSync.AzureKeyVault, .extend({
AzureKeyVaultSyncOptionsConfig destination: z.literal(SecretSync.AzureKeyVault),
).extend({ destinationConfig: AzureKeyVaultSyncDestinationConfigSchema
destination: z.literal(SecretSync.AzureKeyVault), })
destinationConfig: AzureKeyVaultSyncDestinationConfigSchema .describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureKeyVault] }));
});
export const CreateAzureKeyVaultSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateAzureKeyVaultSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.AzureKeyVault, SecretSync.AzureKeyVault,
@@ -42,9 +43,11 @@ export const UpdateAzureKeyVaultSyncSchema = GenericUpdateSecretSyncFieldsSchema
destinationConfig: AzureKeyVaultSyncDestinationConfigSchema.optional() destinationConfig: AzureKeyVaultSyncDestinationConfigSchema.optional()
}); });
export const AzureKeyVaultSyncListItemSchema = z.object({ export const AzureKeyVaultSyncListItemSchema = z
name: z.literal("Azure Key Vault"), .object({
connection: z.literal(AppConnection.AzureKeyVault), name: z.literal("Azure Key Vault"),
destination: z.literal(SecretSync.AzureKeyVault), connection: z.literal(AppConnection.AzureKeyVault),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.AzureKeyVault),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.AzureKeyVault] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const BitbucketSyncDestinationConfigSchema = z.object({ const BitbucketSyncDestinationConfigSchema = z.object({
repositorySlug: z.string().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.repositorySlug), repositorySlug: z.string().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.repositorySlug),
environmentId: z.string().optional().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.environmentId), environmentId: z.string().optional().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.environmentId),
@@ -18,10 +20,12 @@ const BitbucketSyncDestinationConfigSchema = z.object({
const BitbucketSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; const BitbucketSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const BitbucketSyncSchema = BaseSecretSyncSchema(SecretSync.Bitbucket, BitbucketSyncOptionsConfig).extend({ export const BitbucketSyncSchema = BaseSecretSyncSchema(SecretSync.Bitbucket, BitbucketSyncOptionsConfig)
destination: z.literal(SecretSync.Bitbucket), .extend({
destinationConfig: BitbucketSyncDestinationConfigSchema destination: z.literal(SecretSync.Bitbucket),
}); destinationConfig: BitbucketSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Bitbucket] }));
export const CreateBitbucketSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateBitbucketSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Bitbucket, SecretSync.Bitbucket,
@@ -37,9 +41,11 @@ export const UpdateBitbucketSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: BitbucketSyncDestinationConfigSchema.optional() destinationConfig: BitbucketSyncDestinationConfigSchema.optional()
}); });
export const BitbucketSyncListItemSchema = z.object({ export const BitbucketSyncListItemSchema = z
name: z.literal("Bitbucket"), .object({
connection: z.literal(AppConnection.Bitbucket), name: z.literal("Bitbucket"),
destination: z.literal(SecretSync.Bitbucket), connection: z.literal(AppConnection.Bitbucket),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.Bitbucket),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Bitbucket] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const CamundaSyncDestinationConfigSchema = z.object({ const CamundaSyncDestinationConfigSchema = z.object({
scope: z.string().trim().min(1, "Camunda scope required").describe(SecretSyncs.DESTINATION_CONFIG.CAMUNDA.scope), scope: z.string().trim().min(1, "Camunda scope required").describe(SecretSyncs.DESTINATION_CONFIG.CAMUNDA.scope),
clusterUUID: z clusterUUID: z
@@ -20,10 +22,12 @@ const CamundaSyncDestinationConfigSchema = z.object({
const CamundaSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const CamundaSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const CamundaSyncSchema = BaseSecretSyncSchema(SecretSync.Camunda, CamundaSyncOptionsConfig).extend({ export const CamundaSyncSchema = BaseSecretSyncSchema(SecretSync.Camunda, CamundaSyncOptionsConfig)
destination: z.literal(SecretSync.Camunda), .extend({
destinationConfig: CamundaSyncDestinationConfigSchema destination: z.literal(SecretSync.Camunda),
}); destinationConfig: CamundaSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Camunda] }));
export const CreateCamundaSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateCamundaSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Camunda, SecretSync.Camunda,
@@ -39,9 +43,11 @@ export const UpdateCamundaSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: CamundaSyncDestinationConfigSchema.optional() destinationConfig: CamundaSyncDestinationConfigSchema.optional()
}); });
export const CamundaSyncListItemSchema = z.object({ export const CamundaSyncListItemSchema = z
name: z.literal("Camunda"), .object({
connection: z.literal(AppConnection.Camunda), name: z.literal("Camunda"),
destination: z.literal(SecretSync.Camunda), connection: z.literal(AppConnection.Camunda),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Camunda),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Camunda] }));
@@ -9,6 +9,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const ChecklySyncDestinationConfigSchema = z.object({ const ChecklySyncDestinationConfigSchema = z.object({
accountId: z.string().min(1, "Account ID is required").max(255, "Account ID must be less than 255 characters"), accountId: z.string().min(1, "Account ID is required").max(255, "Account ID must be less than 255 characters"),
accountName: z accountName: z
@@ -26,10 +28,12 @@ const ChecklySyncDestinationConfigSchema = z.object({
const ChecklySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; const ChecklySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const ChecklySyncSchema = BaseSecretSyncSchema(SecretSync.Checkly, ChecklySyncOptionsConfig).extend({ export const ChecklySyncSchema = BaseSecretSyncSchema(SecretSync.Checkly, ChecklySyncOptionsConfig)
destination: z.literal(SecretSync.Checkly), .extend({
destinationConfig: ChecklySyncDestinationConfigSchema destination: z.literal(SecretSync.Checkly),
}); destinationConfig: ChecklySyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Checkly] }));
export const CreateChecklySyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateChecklySyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Checkly, SecretSync.Checkly,
@@ -45,9 +49,11 @@ export const UpdateChecklySyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: ChecklySyncDestinationConfigSchema.optional() destinationConfig: ChecklySyncDestinationConfigSchema.optional()
}); });
export const ChecklySyncListItemSchema = z.object({ export const ChecklySyncListItemSchema = z
name: z.literal("Checkly"), .object({
connection: z.literal(AppConnection.Checkly), name: z.literal("Checkly"),
destination: z.literal(SecretSync.Checkly), connection: z.literal(AppConnection.Checkly),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.Checkly),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Checkly] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const CloudflarePagesSyncDestinationConfigSchema = z.object({ const CloudflarePagesSyncDestinationConfigSchema = z.object({
projectName: z projectName: z
.string() .string()
@@ -26,10 +28,12 @@ const CloudflarePagesSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets:
export const CloudflarePagesSyncSchema = BaseSecretSyncSchema( export const CloudflarePagesSyncSchema = BaseSecretSyncSchema(
SecretSync.CloudflarePages, SecretSync.CloudflarePages,
CloudflarePagesSyncOptionsConfig CloudflarePagesSyncOptionsConfig
).extend({ )
destination: z.literal(SecretSync.CloudflarePages), .extend({
destinationConfig: CloudflarePagesSyncDestinationConfigSchema destination: z.literal(SecretSync.CloudflarePages),
}); destinationConfig: CloudflarePagesSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.CloudflarePages] }));
export const CreateCloudflarePagesSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateCloudflarePagesSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.CloudflarePages, SecretSync.CloudflarePages,
@@ -45,9 +49,11 @@ export const UpdateCloudflarePagesSyncSchema = GenericUpdateSecretSyncFieldsSche
destinationConfig: CloudflarePagesSyncDestinationConfigSchema.optional() destinationConfig: CloudflarePagesSyncDestinationConfigSchema.optional()
}); });
export const CloudflarePagesSyncListItemSchema = z.object({ export const CloudflarePagesSyncListItemSchema = z
name: z.literal("Cloudflare Pages"), .object({
connection: z.literal(AppConnection.Cloudflare), name: z.literal("Cloudflare Pages"),
destination: z.literal(SecretSync.CloudflarePages), connection: z.literal(AppConnection.Cloudflare),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.CloudflarePages),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.CloudflarePages] }));
@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const CloudflareWorkersSyncDestinationConfigSchema = z.object({ const CloudflareWorkersSyncDestinationConfigSchema = z.object({
scriptId: z scriptId: z
.string() .string()
@@ -28,10 +30,12 @@ const CloudflareWorkersSyncOptionsConfig: TSyncOptionsConfig = { canImportSecret
export const CloudflareWorkersSyncSchema = BaseSecretSyncSchema( export const CloudflareWorkersSyncSchema = BaseSecretSyncSchema(
SecretSync.CloudflareWorkers, SecretSync.CloudflareWorkers,
CloudflareWorkersSyncOptionsConfig CloudflareWorkersSyncOptionsConfig
).extend({ )
destination: z.literal(SecretSync.CloudflareWorkers), .extend({
destinationConfig: CloudflareWorkersSyncDestinationConfigSchema destination: z.literal(SecretSync.CloudflareWorkers),
}); destinationConfig: CloudflareWorkersSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.CloudflareWorkers] }));
export const CreateCloudflareWorkersSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateCloudflareWorkersSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.CloudflareWorkers, SecretSync.CloudflareWorkers,
@@ -47,9 +51,11 @@ export const UpdateCloudflareWorkersSyncSchema = GenericUpdateSecretSyncFieldsSc
destinationConfig: CloudflareWorkersSyncDestinationConfigSchema.optional() destinationConfig: CloudflareWorkersSyncDestinationConfigSchema.optional()
}); });
export const CloudflareWorkersSyncListItemSchema = z.object({ export const CloudflareWorkersSyncListItemSchema = z
name: z.literal("Cloudflare Workers"), .object({
connection: z.literal(AppConnection.Cloudflare), name: z.literal("Cloudflare Workers"),
destination: z.literal(SecretSync.CloudflareWorkers), connection: z.literal(AppConnection.Cloudflare),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.CloudflareWorkers),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.CloudflareWorkers] }));
@@ -10,16 +10,20 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const DatabricksSyncDestinationConfigSchema = z.object({ const DatabricksSyncDestinationConfigSchema = z.object({
scope: z.string().trim().min(1, "Databricks scope required").describe(SecretSyncs.DESTINATION_CONFIG.DATABRICKS.scope) scope: z.string().trim().min(1, "Databricks scope required").describe(SecretSyncs.DESTINATION_CONFIG.DATABRICKS.scope)
}); });
const DatabricksSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; const DatabricksSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const DatabricksSyncSchema = BaseSecretSyncSchema(SecretSync.Databricks, DatabricksSyncOptionsConfig).extend({ export const DatabricksSyncSchema = BaseSecretSyncSchema(SecretSync.Databricks, DatabricksSyncOptionsConfig)
destination: z.literal(SecretSync.Databricks), .extend({
destinationConfig: DatabricksSyncDestinationConfigSchema destination: z.literal(SecretSync.Databricks),
}); destinationConfig: DatabricksSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Databricks] }));
export const CreateDatabricksSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateDatabricksSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Databricks, SecretSync.Databricks,
@@ -35,9 +39,11 @@ export const UpdateDatabricksSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: DatabricksSyncDestinationConfigSchema.optional() destinationConfig: DatabricksSyncDestinationConfigSchema.optional()
}); });
export const DatabricksSyncListItemSchema = z.object({ export const DatabricksSyncListItemSchema = z
name: z.literal("Databricks"), .object({
connection: z.literal(AppConnection.Databricks), name: z.literal("Databricks"),
destination: z.literal(SecretSync.Databricks), connection: z.literal(AppConnection.Databricks),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.Databricks),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Databricks] }));
@@ -9,6 +9,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const DigitalOceanAppPlatformSyncDestinationConfigSchema = z.object({ const DigitalOceanAppPlatformSyncDestinationConfigSchema = z.object({
appId: z.string().min(1, "Account ID is required").max(255, "Account ID must be less than 255 characters"), 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") 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( export const DigitalOceanAppPlatformSyncSchema = BaseSecretSyncSchema(
SecretSync.DigitalOceanAppPlatform, SecretSync.DigitalOceanAppPlatform,
DigitalOceanAppPlatformSyncOptionsConfig DigitalOceanAppPlatformSyncOptionsConfig
).extend({ )
destination: z.literal(SecretSync.DigitalOceanAppPlatform), .extend({
destinationConfig: DigitalOceanAppPlatformSyncDestinationConfigSchema destination: z.literal(SecretSync.DigitalOceanAppPlatform),
}); destinationConfig: DigitalOceanAppPlatformSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.DigitalOceanAppPlatform] }));
export const CreateDigitalOceanAppPlatformSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateDigitalOceanAppPlatformSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.DigitalOceanAppPlatform, SecretSync.DigitalOceanAppPlatform,
@@ -38,9 +42,11 @@ export const UpdateDigitalOceanAppPlatformSyncSchema = GenericUpdateSecretSyncFi
destinationConfig: DigitalOceanAppPlatformSyncDestinationConfigSchema.optional() destinationConfig: DigitalOceanAppPlatformSyncDestinationConfigSchema.optional()
}); });
export const DigitalOceanAppPlatformSyncListItemSchema = z.object({ export const DigitalOceanAppPlatformSyncListItemSchema = z
name: z.literal("Digital Ocean App Platform"), .object({
connection: z.literal(AppConnection.DigitalOcean), name: z.literal("Digital Ocean App Platform"),
destination: z.literal(SecretSync.DigitalOceanAppPlatform), connection: z.literal(AppConnection.DigitalOcean),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.DigitalOceanAppPlatform),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.DigitalOceanAppPlatform] }));
@@ -10,16 +10,20 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const FlyioSyncDestinationConfigSchema = z.object({ const FlyioSyncDestinationConfigSchema = z.object({
appId: z.string().trim().min(1, "App required").max(255).describe(SecretSyncs.DESTINATION_CONFIG.FLYIO.appId) appId: z.string().trim().min(1, "App required").max(255).describe(SecretSyncs.DESTINATION_CONFIG.FLYIO.appId)
}); });
const FlyioSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; const FlyioSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const FlyioSyncSchema = BaseSecretSyncSchema(SecretSync.Flyio, FlyioSyncOptionsConfig).extend({ export const FlyioSyncSchema = BaseSecretSyncSchema(SecretSync.Flyio, FlyioSyncOptionsConfig)
destination: z.literal(SecretSync.Flyio), .extend({
destinationConfig: FlyioSyncDestinationConfigSchema destination: z.literal(SecretSync.Flyio),
}); destinationConfig: FlyioSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Flyio] }));
export const CreateFlyioSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateFlyioSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Flyio, SecretSync.Flyio,
@@ -35,9 +39,11 @@ export const UpdateFlyioSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: FlyioSyncDestinationConfigSchema.optional() destinationConfig: FlyioSyncDestinationConfigSchema.optional()
}); });
export const FlyioSyncListItemSchema = z.object({ export const FlyioSyncListItemSchema = z
name: z.literal("Fly.io"), .object({
connection: z.literal(AppConnection.Flyio), name: z.literal("Fly.io"),
destination: z.literal(SecretSync.Flyio), connection: z.literal(AppConnection.Flyio),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.Flyio),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Flyio] }));
@@ -10,6 +10,7 @@ import {
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SecretSync } from "../secret-sync-enums"; import { SecretSync } from "../secret-sync-enums";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
import { GCPSecretManagerLocation, GcpSyncScope } from "./gcp-sync-enums"; import { GCPSecretManagerLocation, GcpSyncScope } from "./gcp-sync-enums";
const GcpSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const GcpSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
@@ -38,10 +39,12 @@ const GcpSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
) )
]); ]);
export const GcpSyncSchema = BaseSecretSyncSchema(SecretSync.GCPSecretManager, GcpSyncOptionsConfig).extend({ export const GcpSyncSchema = BaseSecretSyncSchema(SecretSync.GCPSecretManager, GcpSyncOptionsConfig)
destination: z.literal(SecretSync.GCPSecretManager), .extend({
destinationConfig: GcpSyncDestinationConfigSchema destination: z.literal(SecretSync.GCPSecretManager),
}); destinationConfig: GcpSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GCPSecretManager] }));
export const CreateGcpSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateGcpSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.GCPSecretManager, SecretSync.GCPSecretManager,
@@ -57,9 +60,11 @@ export const UpdateGcpSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: GcpSyncDestinationConfigSchema.optional() destinationConfig: GcpSyncDestinationConfigSchema.optional()
}); });
export const GcpSyncListItemSchema = z.object({ export const GcpSyncListItemSchema = z
name: z.literal("GCP Secret Manager"), .object({
connection: z.literal(AppConnection.GCP), name: z.literal("GCP Secret Manager"),
destination: z.literal(SecretSync.GCPSecretManager), connection: z.literal(AppConnection.GCP),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.GCPSecretManager),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GCPSecretManager] }));
@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const GitHubSyncDestinationConfigSchema = z const GitHubSyncDestinationConfigSchema = z
.discriminatedUnion("scope", [ .discriminatedUnion("scope", [
z.object({ z.object({
@@ -55,10 +57,12 @@ const GitHubSyncDestinationConfigSchema = z
const GitHubSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; const GitHubSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const GitHubSyncSchema = BaseSecretSyncSchema(SecretSync.GitHub, GitHubSyncOptionsConfig).extend({ export const GitHubSyncSchema = BaseSecretSyncSchema(SecretSync.GitHub, GitHubSyncOptionsConfig)
destination: z.literal(SecretSync.GitHub), .extend({
destinationConfig: GitHubSyncDestinationConfigSchema destination: z.literal(SecretSync.GitHub),
}); destinationConfig: GitHubSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GitHub] }));
export const CreateGitHubSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateGitHubSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.GitHub, SecretSync.GitHub,
@@ -74,9 +78,11 @@ export const UpdateGitHubSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: GitHubSyncDestinationConfigSchema.optional() destinationConfig: GitHubSyncDestinationConfigSchema.optional()
}); });
export const GitHubSyncListItemSchema = z.object({ export const GitHubSyncListItemSchema = z
name: z.literal("GitHub"), .object({
connection: z.literal(AppConnection.GitHub), name: z.literal("GitHub"),
destination: z.literal(SecretSync.GitHub), connection: z.literal(AppConnection.GitHub),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.GitHub),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GitHub] }));
@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; 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"; import { GitLabSyncScope } from "./gitlab-sync-enums";
const GitLabSyncDestinationConfigSchema = z.discriminatedUnion("scope", [ const GitLabSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
@@ -70,10 +71,12 @@ const GitLabSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
const GitLabSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; const GitLabSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const GitLabSyncSchema = BaseSecretSyncSchema(SecretSync.GitLab, GitLabSyncOptionsConfig).extend({ export const GitLabSyncSchema = BaseSecretSyncSchema(SecretSync.GitLab, GitLabSyncOptionsConfig)
destination: z.literal(SecretSync.GitLab), .extend({
destinationConfig: GitLabSyncDestinationConfigSchema destination: z.literal(SecretSync.GitLab),
}); destinationConfig: GitLabSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GitLab] }));
export const CreateGitLabSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateGitLabSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.GitLab, SecretSync.GitLab,
@@ -89,9 +92,11 @@ export const UpdateGitLabSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: GitLabSyncDestinationConfigSchema.optional() destinationConfig: GitLabSyncDestinationConfigSchema.optional()
}); });
export const GitLabSyncListItemSchema = z.object({ export const GitLabSyncListItemSchema = z
name: z.literal("GitLab"), .object({
connection: z.literal(AppConnection.GitLab), name: z.literal("GitLab"),
destination: z.literal(SecretSync.GitLab), connection: z.literal(AppConnection.GitLab),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.GitLab),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.GitLab] }));
@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const HCVaultSyncDestinationConfigSchema = z.object({ const HCVaultSyncDestinationConfigSchema = z.object({
mount: z mount: z
.string() .string()
@@ -33,10 +35,12 @@ const HCVaultSyncDestinationConfigSchema = z.object({
const HCVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const HCVaultSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const HCVaultSyncSchema = BaseSecretSyncSchema(SecretSync.HCVault, HCVaultSyncOptionsConfig).extend({ export const HCVaultSyncSchema = BaseSecretSyncSchema(SecretSync.HCVault, HCVaultSyncOptionsConfig)
destination: z.literal(SecretSync.HCVault), .extend({
destinationConfig: HCVaultSyncDestinationConfigSchema destination: z.literal(SecretSync.HCVault),
}); destinationConfig: HCVaultSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.HCVault] }));
export const CreateHCVaultSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateHCVaultSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.HCVault, SecretSync.HCVault,
@@ -52,9 +56,11 @@ export const UpdateHCVaultSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: HCVaultSyncDestinationConfigSchema.optional() destinationConfig: HCVaultSyncDestinationConfigSchema.optional()
}); });
export const HCVaultSyncListItemSchema = z.object({ export const HCVaultSyncListItemSchema = z
name: z.literal("Hashicorp Vault"), .object({
connection: z.literal(AppConnection.HCVault), name: z.literal("Hashicorp Vault"),
destination: z.literal(SecretSync.HCVault), connection: z.literal(AppConnection.HCVault),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.HCVault),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.HCVault] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const HerokuSyncDestinationConfigSchema = z.object({ const HerokuSyncDestinationConfigSchema = z.object({
app: z.string().trim().min(1, "App required").describe(SecretSyncs.DESTINATION_CONFIG.HEROKU.app), 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) 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 }; const HerokuSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const HerokuSyncSchema = BaseSecretSyncSchema(SecretSync.Heroku, HerokuSyncOptionsConfig).extend({ export const HerokuSyncSchema = BaseSecretSyncSchema(SecretSync.Heroku, HerokuSyncOptionsConfig)
destination: z.literal(SecretSync.Heroku), .extend({
destinationConfig: HerokuSyncDestinationConfigSchema destination: z.literal(SecretSync.Heroku),
}); destinationConfig: HerokuSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Heroku] }));
export const CreateHerokuSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateHerokuSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Heroku, SecretSync.Heroku,
@@ -36,9 +40,11 @@ export const UpdateHerokuSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: HerokuSyncDestinationConfigSchema.optional() destinationConfig: HerokuSyncDestinationConfigSchema.optional()
}); });
export const HerokuSyncListItemSchema = z.object({ export const HerokuSyncListItemSchema = z
name: z.literal("Heroku"), .object({
connection: z.literal(AppConnection.Heroku), name: z.literal("Heroku"),
destination: z.literal(SecretSync.Heroku), connection: z.literal(AppConnection.Heroku),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Heroku),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Heroku] }));
@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const HumanitecSyncDestinationConfigSchema = z.discriminatedUnion("scope", [ const HumanitecSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
z.object({ z.object({
scope: z.literal(HumanitecSyncScope.Application).describe(SecretSyncs.DESTINATION_CONFIG.HUMANITEC.scope), 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 }; const HumanitecSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const HumanitecSyncSchema = BaseSecretSyncSchema(SecretSync.Humanitec, HumanitecSyncOptionsConfig).extend({ export const HumanitecSyncSchema = BaseSecretSyncSchema(SecretSync.Humanitec, HumanitecSyncOptionsConfig)
destination: z.literal(SecretSync.Humanitec), .extend({
destinationConfig: HumanitecSyncDestinationConfigSchema destination: z.literal(SecretSync.Humanitec),
}); destinationConfig: HumanitecSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Humanitec] }));
export const CreateHumanitecSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateHumanitecSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Humanitec, SecretSync.Humanitec,
@@ -46,9 +50,11 @@ export const UpdateHumanitecSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: HumanitecSyncDestinationConfigSchema.optional() destinationConfig: HumanitecSyncDestinationConfigSchema.optional()
}); });
export const HumanitecSyncListItemSchema = z.object({ export const HumanitecSyncListItemSchema = z
name: z.literal("Humanitec"), .object({
connection: z.literal(AppConnection.Humanitec), name: z.literal("Humanitec"),
destination: z.literal(SecretSync.Humanitec), connection: z.literal(AppConnection.Humanitec),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.Humanitec),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Humanitec] }));
@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const slugValidator = (val: string) => { const slugValidator = (val: string) => {
return new RE2("^[a-z0-9.-]+$").test(val) && !new RE2(".[-]$").test(val); 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 }; const LaravelForgeSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const LaravelForgeSyncSchema = BaseSecretSyncSchema( export const LaravelForgeSyncSchema = BaseSecretSyncSchema(SecretSync.LaravelForge, LaravelForgeSyncOptionsConfig)
SecretSync.LaravelForge, .extend({
LaravelForgeSyncOptionsConfig destination: z.literal(SecretSync.LaravelForge),
).extend({ destinationConfig: LaravelForgeSyncDestinationConfigSchema
destination: z.literal(SecretSync.LaravelForge), })
destinationConfig: LaravelForgeSyncDestinationConfigSchema .describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.LaravelForge] }));
});
export const CreateLaravelForgeSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateLaravelForgeSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.LaravelForge, SecretSync.LaravelForge,
@@ -60,9 +61,11 @@ export const UpdateLaravelForgeSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: LaravelForgeSyncDestinationConfigSchema.optional() destinationConfig: LaravelForgeSyncDestinationConfigSchema.optional()
}); });
export const LaravelForgeSyncListItemSchema = z.object({ export const LaravelForgeSyncListItemSchema = z
name: z.literal("Laravel Forge"), .object({
connection: z.literal(AppConnection.LaravelForge), name: z.literal("Laravel Forge"),
destination: z.literal(SecretSync.LaravelForge), connection: z.literal(AppConnection.LaravelForge),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.LaravelForge),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.LaravelForge] }));
@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; 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"; import { NetlifySyncContext } from "./netlify-sync-constants";
const NetlifySyncDestinationConfigSchema = z.object({ const NetlifySyncDestinationConfigSchema = z.object({
@@ -41,10 +42,12 @@ const NetlifySyncDestinationConfigSchema = z.object({
const NetlifySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const NetlifySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const NetlifySyncSchema = BaseSecretSyncSchema(SecretSync.Netlify, NetlifySyncOptionsConfig).extend({ export const NetlifySyncSchema = BaseSecretSyncSchema(SecretSync.Netlify, NetlifySyncOptionsConfig)
destination: z.literal(SecretSync.Netlify), .extend({
destinationConfig: NetlifySyncDestinationConfigSchema destination: z.literal(SecretSync.Netlify),
}); destinationConfig: NetlifySyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Netlify] }));
export const CreateNetlifySyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateNetlifySyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Netlify, SecretSync.Netlify,
@@ -60,9 +63,11 @@ export const UpdateNetlifySyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: NetlifySyncDestinationConfigSchema.optional() destinationConfig: NetlifySyncDestinationConfigSchema.optional()
}); });
export const NetlifySyncListItemSchema = z.object({ export const NetlifySyncListItemSchema = z
name: z.literal("Netlify"), .object({
connection: z.literal(AppConnection.Netlify), name: z.literal("Netlify"),
destination: z.literal(SecretSync.Netlify), connection: z.literal(AppConnection.Netlify),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Netlify),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Netlify] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const NorthflankSyncDestinationConfigSchema = z.object({ const NorthflankSyncDestinationConfigSchema = z.object({
projectId: z projectId: z
.string() .string()
@@ -27,10 +29,12 @@ const NorthflankSyncDestinationConfigSchema = z.object({
const NorthflankSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const NorthflankSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const NorthflankSyncSchema = BaseSecretSyncSchema(SecretSync.Northflank, NorthflankSyncOptionsConfig).extend({ export const NorthflankSyncSchema = BaseSecretSyncSchema(SecretSync.Northflank, NorthflankSyncOptionsConfig)
destination: z.literal(SecretSync.Northflank), .extend({
destinationConfig: NorthflankSyncDestinationConfigSchema destination: z.literal(SecretSync.Northflank),
}); destinationConfig: NorthflankSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Northflank] }));
export const CreateNorthflankSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateNorthflankSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Northflank, SecretSync.Northflank,
@@ -46,9 +50,11 @@ export const UpdateNorthflankSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: NorthflankSyncDestinationConfigSchema.optional() destinationConfig: NorthflankSyncDestinationConfigSchema.optional()
}); });
export const NorthflankSyncListItemSchema = z.object({ export const NorthflankSyncListItemSchema = z
name: z.literal("Northflank"), .object({
connection: z.literal(AppConnection.Northflank), name: z.literal("Northflank"),
destination: z.literal(SecretSync.Northflank), connection: z.literal(AppConnection.Northflank),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Northflank),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Northflank] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const RailwaySyncDestinationConfigSchema = z.object({ const RailwaySyncDestinationConfigSchema = z.object({
projectId: z projectId: z
.string() .string()
@@ -29,10 +31,12 @@ const RailwaySyncDestinationConfigSchema = z.object({
const RailwaySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const RailwaySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const RailwaySyncSchema = BaseSecretSyncSchema(SecretSync.Railway, RailwaySyncOptionsConfig).extend({ export const RailwaySyncSchema = BaseSecretSyncSchema(SecretSync.Railway, RailwaySyncOptionsConfig)
destination: z.literal(SecretSync.Railway), .extend({
destinationConfig: RailwaySyncDestinationConfigSchema destination: z.literal(SecretSync.Railway),
}); destinationConfig: RailwaySyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Railway] }));
export const CreateRailwaySyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateRailwaySyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Railway, SecretSync.Railway,
@@ -48,9 +52,11 @@ export const UpdateRailwaySyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: RailwaySyncDestinationConfigSchema.optional() destinationConfig: RailwaySyncDestinationConfigSchema.optional()
}); });
export const RailwaySyncListItemSchema = z.object({ export const RailwaySyncListItemSchema = z
name: z.literal("Railway"), .object({
connection: z.literal(AppConnection.Railway), name: z.literal("Railway"),
destination: z.literal(SecretSync.Railway), connection: z.literal(AppConnection.Railway),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Railway),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Railway] }));
@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; 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"; import { RenderSyncScope, RenderSyncType } from "./render-sync-enums";
const RenderSyncDestinationConfigSchema = z.discriminatedUnion("scope", [ const RenderSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
@@ -38,10 +39,12 @@ export const RenderSyncSchema = BaseSecretSyncSchema(
SecretSync.Render, SecretSync.Render,
RenderSyncOptionsConfig, RenderSyncOptionsConfig,
RenderSyncOptionsSchema RenderSyncOptionsSchema
).extend({ )
destination: z.literal(SecretSync.Render), .extend({
destinationConfig: RenderSyncDestinationConfigSchema destination: z.literal(SecretSync.Render),
}); destinationConfig: RenderSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Render] }));
export const CreateRenderSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateRenderSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Render, SecretSync.Render,
@@ -59,9 +62,11 @@ export const UpdateRenderSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: RenderSyncDestinationConfigSchema.optional() destinationConfig: RenderSyncDestinationConfigSchema.optional()
}); });
export const RenderSyncListItemSchema = z.object({ export const RenderSyncListItemSchema = z
name: z.literal("Render"), .object({
connection: z.literal(AppConnection.Render), name: z.literal("Render"),
destination: z.literal(SecretSync.Render), connection: z.literal(AppConnection.Render),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Render),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Render] }));
@@ -9,6 +9,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const SupabaseSyncDestinationConfigSchema = z.object({ const SupabaseSyncDestinationConfigSchema = z.object({
projectId: z.string().max(255).min(1, "Project ID is required"), projectId: z.string().max(255).min(1, "Project ID is required"),
projectName: z.string().max(255).min(1, "Project Name 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 }; const SupabaseSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const SupabaseSyncSchema = BaseSecretSyncSchema(SecretSync.Supabase, SupabaseSyncOptionsConfig).extend({ export const SupabaseSyncSchema = BaseSecretSyncSchema(SecretSync.Supabase, SupabaseSyncOptionsConfig)
destination: z.literal(SecretSync.Supabase), .extend({
destinationConfig: SupabaseSyncDestinationConfigSchema destination: z.literal(SecretSync.Supabase),
}); destinationConfig: SupabaseSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Supabase] }));
export const CreateSupabaseSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateSupabaseSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Supabase, SecretSync.Supabase,
@@ -35,9 +39,11 @@ export const UpdateSupabaseSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: SupabaseSyncDestinationConfigSchema.optional() destinationConfig: SupabaseSyncDestinationConfigSchema.optional()
}); });
export const SupabaseSyncListItemSchema = z.object({ export const SupabaseSyncListItemSchema = z
name: z.literal("Supabase"), .object({
connection: z.literal(AppConnection.Supabase), name: z.literal("Supabase"),
destination: z.literal(SecretSync.Supabase), connection: z.literal(AppConnection.Supabase),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.Supabase),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Supabase] }));
@@ -10,6 +10,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const TeamCitySyncDestinationConfigSchema = z.object({ const TeamCitySyncDestinationConfigSchema = z.object({
project: z.string().trim().min(1, "Project required").describe(SecretSyncs.DESTINATION_CONFIG.TEAMCITY.project), 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) buildConfig: z.string().trim().optional().describe(SecretSyncs.DESTINATION_CONFIG.TEAMCITY.buildConfig)
@@ -17,10 +19,12 @@ const TeamCitySyncDestinationConfigSchema = z.object({
const TeamCitySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const TeamCitySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const TeamCitySyncSchema = BaseSecretSyncSchema(SecretSync.TeamCity, TeamCitySyncOptionsConfig).extend({ export const TeamCitySyncSchema = BaseSecretSyncSchema(SecretSync.TeamCity, TeamCitySyncOptionsConfig)
destination: z.literal(SecretSync.TeamCity), .extend({
destinationConfig: TeamCitySyncDestinationConfigSchema destination: z.literal(SecretSync.TeamCity),
}); destinationConfig: TeamCitySyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.TeamCity] }));
export const CreateTeamCitySyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateTeamCitySyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.TeamCity, SecretSync.TeamCity,
@@ -36,9 +40,11 @@ export const UpdateTeamCitySyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: TeamCitySyncDestinationConfigSchema.optional() destinationConfig: TeamCitySyncDestinationConfigSchema.optional()
}); });
export const TeamCitySyncListItemSchema = z.object({ export const TeamCitySyncListItemSchema = z
name: z.literal("TeamCity"), .object({
connection: z.literal(AppConnection.TeamCity), name: z.literal("TeamCity"),
destination: z.literal(SecretSync.TeamCity), connection: z.literal(AppConnection.TeamCity),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.TeamCity),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.TeamCity] }));
@@ -14,6 +14,8 @@ import {
TerraformCloudSyncScope TerraformCloudSyncScope
} from "@app/services/secret-sync/terraform-cloud/terraform-cloud-sync-enums"; } 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", [ const TerraformCloudSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
z.object({ z.object({
scope: z scope: z
@@ -47,13 +49,12 @@ const TerraformCloudSyncDestinationConfigSchema = z.discriminatedUnion("scope",
const TerraformCloudSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; const TerraformCloudSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false };
export const TerraformCloudSyncSchema = BaseSecretSyncSchema( export const TerraformCloudSyncSchema = BaseSecretSyncSchema(SecretSync.TerraformCloud, TerraformCloudSyncOptionsConfig)
SecretSync.TerraformCloud, .extend({
TerraformCloudSyncOptionsConfig destination: z.literal(SecretSync.TerraformCloud),
).extend({ destinationConfig: TerraformCloudSyncDestinationConfigSchema
destination: z.literal(SecretSync.TerraformCloud), })
destinationConfig: TerraformCloudSyncDestinationConfigSchema .describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.TerraformCloud] }));
});
export const CreateTerraformCloudSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateTerraformCloudSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.TerraformCloud, SecretSync.TerraformCloud,
@@ -69,9 +70,11 @@ export const UpdateTerraformCloudSyncSchema = GenericUpdateSecretSyncFieldsSchem
destinationConfig: TerraformCloudSyncDestinationConfigSchema.optional() destinationConfig: TerraformCloudSyncDestinationConfigSchema.optional()
}); });
export const TerraformCloudSyncListItemSchema = z.object({ export const TerraformCloudSyncListItemSchema = z
name: z.literal("Terraform Cloud"), .object({
connection: z.literal(AppConnection.TerraformCloud), name: z.literal("Terraform Cloud"),
destination: z.literal(SecretSync.TerraformCloud), connection: z.literal(AppConnection.TerraformCloud),
canImportSecrets: z.literal(false) destination: z.literal(SecretSync.TerraformCloud),
}); canImportSecrets: z.literal(false)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.TerraformCloud] }));
@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; 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"; import { VercelEnvironmentType } from "./vercel-sync-enums";
const VercelSyncDestinationConfigSchema = z.object({ const VercelSyncDestinationConfigSchema = z.object({
@@ -22,10 +23,12 @@ const VercelSyncDestinationConfigSchema = z.object({
const VercelSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const VercelSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const VercelSyncSchema = BaseSecretSyncSchema(SecretSync.Vercel, VercelSyncOptionsConfig).extend({ export const VercelSyncSchema = BaseSecretSyncSchema(SecretSync.Vercel, VercelSyncOptionsConfig)
destination: z.literal(SecretSync.Vercel), .extend({
destinationConfig: VercelSyncDestinationConfigSchema destination: z.literal(SecretSync.Vercel),
}); destinationConfig: VercelSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Vercel] }));
export const CreateVercelSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateVercelSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Vercel, SecretSync.Vercel,
@@ -41,9 +44,11 @@ export const UpdateVercelSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: VercelSyncDestinationConfigSchema.optional() destinationConfig: VercelSyncDestinationConfigSchema.optional()
}); });
export const VercelSyncListItemSchema = z.object({ export const VercelSyncListItemSchema = z
name: z.literal("Vercel"), .object({
connection: z.literal(AppConnection.Vercel), name: z.literal("Vercel"),
destination: z.literal(SecretSync.Vercel), connection: z.literal(AppConnection.Vercel),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Vercel),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Vercel] }));
@@ -11,6 +11,8 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types";
import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps";
const pathCharacterValidator = characterValidator([ const pathCharacterValidator = characterValidator([
CharacterType.AlphaNumeric, CharacterType.AlphaNumeric,
CharacterType.Underscore, CharacterType.Underscore,
@@ -39,10 +41,12 @@ const WindmillSyncDestinationConfigSchema = z.object({
const WindmillSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const WindmillSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const WindmillSyncSchema = BaseSecretSyncSchema(SecretSync.Windmill, WindmillSyncOptionsConfig).extend({ export const WindmillSyncSchema = BaseSecretSyncSchema(SecretSync.Windmill, WindmillSyncOptionsConfig)
destination: z.literal(SecretSync.Windmill), .extend({
destinationConfig: WindmillSyncDestinationConfigSchema destination: z.literal(SecretSync.Windmill),
}); destinationConfig: WindmillSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Windmill] }));
export const CreateWindmillSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateWindmillSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Windmill, SecretSync.Windmill,
@@ -58,9 +62,11 @@ export const UpdateWindmillSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: WindmillSyncDestinationConfigSchema.optional() destinationConfig: WindmillSyncDestinationConfigSchema.optional()
}); });
export const WindmillSyncListItemSchema = z.object({ export const WindmillSyncListItemSchema = z
name: z.literal("Windmill"), .object({
connection: z.literal(AppConnection.Windmill), name: z.literal("Windmill"),
destination: z.literal(SecretSync.Windmill), connection: z.literal(AppConnection.Windmill),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Windmill),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Windmill] }));
@@ -10,6 +10,7 @@ import {
} from "@app/services/secret-sync/secret-sync-schemas"; } from "@app/services/secret-sync/secret-sync-schemas";
import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; 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"; import { ZabbixSyncScope } from "./zabbix-sync-enums";
const ZabbixSyncDestinationConfigSchema = z.discriminatedUnion("scope", [ const ZabbixSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
@@ -40,10 +41,12 @@ const ZabbixSyncDestinationConfigSchema = z.discriminatedUnion("scope", [
const ZabbixSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true }; const ZabbixSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: true };
export const ZabbixSyncSchema = BaseSecretSyncSchema(SecretSync.Zabbix, ZabbixSyncOptionsConfig).extend({ export const ZabbixSyncSchema = BaseSecretSyncSchema(SecretSync.Zabbix, ZabbixSyncOptionsConfig)
destination: z.literal(SecretSync.Zabbix), .extend({
destinationConfig: ZabbixSyncDestinationConfigSchema destination: z.literal(SecretSync.Zabbix),
}); destinationConfig: ZabbixSyncDestinationConfigSchema
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Zabbix] }));
export const CreateZabbixSyncSchema = GenericCreateSecretSyncFieldsSchema( export const CreateZabbixSyncSchema = GenericCreateSecretSyncFieldsSchema(
SecretSync.Zabbix, SecretSync.Zabbix,
@@ -59,9 +62,11 @@ export const UpdateZabbixSyncSchema = GenericUpdateSecretSyncFieldsSchema(
destinationConfig: ZabbixSyncDestinationConfigSchema.optional() destinationConfig: ZabbixSyncDestinationConfigSchema.optional()
}); });
export const ZabbixSyncListItemSchema = z.object({ export const ZabbixSyncListItemSchema = z
name: z.literal("Zabbix"), .object({
connection: z.literal(AppConnection.Zabbix), name: z.literal("Zabbix"),
destination: z.literal(SecretSync.Zabbix), connection: z.literal(AppConnection.Zabbix),
canImportSecrets: z.literal(true) destination: z.literal(SecretSync.Zabbix),
}); canImportSecrets: z.literal(true)
})
.describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.Zabbix] }));
+1 -1
View File
@@ -2826,7 +2826,7 @@
"href": "https://infisical.com" "href": "https://infisical.com"
}, },
"api": { "api": {
"openapi": "http://localhost:8080/api/docs/json", "openapi": "https://app.infisical.com/api/docs/json",
"mdx": { "mdx": {
"server": ["https://app.infisical.com"] "server": ["https://app.infisical.com"]
} }
@@ -17,13 +17,13 @@ This guide will provide step by step instructions on how to configure Slack inte
![org-slack-overview](/images/platform/workflow-integrations/slack-integration/org-slack-integration-overview.png) ![org-slack-overview](/images/platform/workflow-integrations/slack-integration/org-slack-integration-overview.png)
</Step> </Step>
<Step title="Install Slack app to workspace"> <Step title="Install Slack app to workspace">
Press "Add" and select "Slack" as the platform. Press **Add** and select **Slack** as the platform.
![org-slack-initial-add](/images/platform/workflow-integrations/slack-integration/org-slack-integration-initial-add.png) ![org-slack-initial-add](/images/platform/workflow-integrations/slack-integration/org-slack-integration-initial-add.png)
Give your Slack integration a descriptive alias. You will use this to select the Slack integration for your project. Give your Slack integration a descriptive alias. You will use this to select the Slack integration for your project.
![org-slack-add-form](/images/platform/workflow-integrations/slack-integration/org-slack-integration-add-form.png) ![org-slack-add-form](/images/platform/workflow-integrations/slack-integration/org-slack-integration-add-form.png)
Press **Connect Slack**. This opens up the Slack app installation flow. Select the Slack workspace you want to install the custom Slack app to and press **Allow**. Press **Connect Slack**. This opens up the Slack app installation flow. Select the Slack workspace you want to install the custom Slack app to and press **Install Infisical**.
![org-slack-authenticate](/images/platform/workflow-integrations/slack-integration/cloud-org-slack-integration-authenticate.png) ![org-slack-authenticate](/images/platform/workflow-integrations/slack-integration/cloud-org-slack-integration-authenticate.png)
This completes the workflow integration creation flow. The projects in your organization can now use this Slack integration to send real-time updates to your Slack workspace. This completes the workflow integration creation flow. The projects in your organization can now use this Slack integration to send real-time updates to your Slack workspace.
@@ -38,6 +38,7 @@ This guide will provide step by step instructions on how to configure Slack inte
<Steps> <Steps>
<Step title="Navigate to the Workflow Integrations tab in the project settings"> <Step title="Navigate to the Workflow Integrations tab in the project settings">
Press **Add** and select **Slack** as the platform.
![project-slack-overview](/images/platform/workflow-integrations/slack-integration/project-slack-integration-overview.png) ![project-slack-overview](/images/platform/workflow-integrations/slack-integration/project-slack-integration-overview.png)
</Step> </Step>
<Step title="Select the Slack integration to use for the project"> <Step title="Select the Slack integration to use for the project">
@@ -66,13 +67,13 @@ This guide will provide step by step instructions on how to configure Slack inte
Before anything else, you need to setup the Slack app to be used by Before anything else, you need to setup the Slack app to be used by
your Infisical instance. Because you're self-hosting, you will need to your Infisical instance. Because you're self-hosting, you will need to
create this Slack application as demonstrated in the preceding step. create this Slack application as demonstrated in the preceding step.
Click the **Create Slack app** button. This will open up a new window with the
custom app creation flow on Slack.
![admin-settings-slack-overview](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-overview.png) ![admin-settings-slack-overview](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-overview.png)
</Step> </Step>
<Step title="Create Slack app"> <Step title="Create Slack app">
Click the "Create Slack app" button. This will open up a new window with the
custom app creation flow on Slack.
![admin-slack-create-app](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-create-app.png)
Select the Slack workspace you want to integrate with Infisical. Select the Slack workspace you want to integrate with Infisical.
![admin-slack-app-workspace-select](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-app-workspace-select.png) ![admin-slack-app-workspace-select](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-app-workspace-select.png)
@@ -87,7 +88,7 @@ This guide will provide step by step instructions on how to configure Slack inte
Copy the Client ID and Client Secret values from your newly created custom Slack app and add them to Infisical. Copy the Client ID and Client Secret values from your newly created custom Slack app and add them to Infisical.
![admin-slack-app-credentials](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-app-credentials.png) ![admin-slack-app-credentials](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-app-credentials.png)
![admin-slack-app-credentials-form](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-app-credential-form.png) ![admin-slack-app-credentials-form](/images/platform/workflow-integrations/slack-integration/admin-slack-integration-app-credential-form.png)
Complete the admin setup by pressing Save. Complete the admin setup by pressing **Save**.
</Step> </Step>
</Steps> </Steps>
@@ -101,13 +102,13 @@ This guide will provide step by step instructions on how to configure Slack inte
![org-slack-overview](/images/platform/workflow-integrations/slack-integration/org-slack-integration-overview.png) ![org-slack-overview](/images/platform/workflow-integrations/slack-integration/org-slack-integration-overview.png)
</Step> </Step>
<Step title="Install Slack app to workspace"> <Step title="Install Slack app to workspace">
Press "Add" and select "Slack" as the platform. Press **Add** and select **Slack** as the platform.
![org-slack-initial-add](/images/platform/workflow-integrations/slack-integration/org-slack-integration-initial-add.png) ![org-slack-initial-add](/images/platform/workflow-integrations/slack-integration/org-slack-integration-initial-add.png)
Give your Slack integration a descriptive alias. You will use this to select the Slack integration for your project. Give your Slack integration a descriptive alias. You will use this to select the Slack integration for your project.
![org-slack-add-form](/images/platform/workflow-integrations/slack-integration/org-slack-integration-add-form.png) ![org-slack-add-form](/images/platform/workflow-integrations/slack-integration/org-slack-integration-add-form.png)
Press **Connect Slack**. This opens up the Slack app installation flow. Select the Slack workspace you want to install the custom Slack app to and press **Allow**. Press **Connect Slack**. This opens up the Slack app installation flow. Select the Slack workspace you want to install the custom Slack app to and press **Install Infisical**.
![org-slack-authenticate](/images/platform/workflow-integrations/slack-integration/org-slack-integration-authenticate.png) ![org-slack-authenticate](/images/platform/workflow-integrations/slack-integration/org-slack-integration-authenticate.png)
Your Slack bot will then be added to your selected Slack workspace. This completes the workflow integration creation flow. Your projects in the organization can now use this Slack integration to send real-time updates to your Slack workspace. Your Slack bot will then be added to your selected Slack workspace. This completes the workflow integration creation flow. Your projects in the organization can now use this Slack integration to send real-time updates to your Slack workspace.
@@ -122,6 +123,7 @@ This guide will provide step by step instructions on how to configure Slack inte
<Steps> <Steps>
<Step title="Navigate to the Workflow Integrations tab in the project settings"> <Step title="Navigate to the Workflow Integrations tab in the project settings">
Press **Add** and select **Slack** as the platform.
![project-slack-overview](/images/platform/workflow-integrations/slack-integration/project-slack-integration-overview.png) ![project-slack-overview](/images/platform/workflow-integrations/slack-integration/project-slack-integration-overview.png)
</Step> </Step>
<Step title="Select the Slack integration to use for the project"> <Step title="Select the Slack integration to use for the project">
@@ -162,3 +164,87 @@ This guide will provide step by step instructions on how to configure Slack inte
channels](/images/platform/workflow-integrations/slack-integration/private-slack-setup-channel-field.png) channels](/images/platform/workflow-integrations/slack-integration/private-slack-setup-channel-field.png)
</Step> </Step>
</Steps> </Steps>
## Slack Events
The Slack integration supports the following events that can be configured for your projects. Each event is triggered when specific actions occur within your Infisical instance.
<Tabs>
<Tab title="Access Request">
### Access Request
This event is triggered when a user creates a new access approval request for a project. The notification includes details about the requester, the requested permissions, the secret path and environment, and whether the access is temporary or permanent.
**When it's triggered:**
- A user submits a new access approval request through the Infisical UI
- The request requires approval based on configured access approval policies
- The notification is sent to the configured access request channels
**Notification includes:**
- Requester's full name and email
- Requested permissions (read, write, etc.)
- Secret path and environment
- Access type (temporary or permanent)
- Optional user note
- Direct link to review the request
![access request notification](/images/platform/workflow-integrations/slack-integration/access-request-notification.png)
### Access Request Updated
This event is triggered when an existing access approval request is modified or updated. This helps approvers stay informed about changes to pending requests.
**When it's triggered:**
- An access approval request is edited by the requester or another authorized user
- Changes are made to permissions, temporary range, or notes
- The notification is sent to the configured access request channels
**Notification includes:**
- Original requester's information
- Editor's full name and email (who made the update)
- Updated permissions
- Updated secret path and environment
- Editor's note explaining the changes
- Direct link to review the updated request
![access request updated notification](/images/platform/workflow-integrations/slack-integration/access-request-updated-notification.png)
</Tab>
<Tab title="Secret Approval">
### Secret Approval
This event is triggered when a secret approval request is created. This occurs when a user attempts to create, update, or delete secrets that require approval based on secret approval policies.
**When it's triggered:**
- A user creates, updates, or deletes secrets in a path protected by a secret approval policy
- The changes require approval before being applied
- The notification is sent to the configured secret request channels
**Notification includes:**
- User's email who initiated the change
- Environment and secret path
- List of secret keys affected
- Direct link to review and approve the secret changes
![secret approval notification](/images/platform/workflow-integrations/slack-integration/secret-approval-notification.png)
</Tab>
<Tab title="Secret Sync Error">
### Secret Sync Error
This event is triggered when a secret sync operation fails. Secret syncs allow you to synchronize secrets between Infisical and external systems like GitHub, GitLab, AWS Secrets Manager, and others.
**When it's triggered:**
- A secret sync fails to push secrets to the destination
- A secret sync fails to pull secrets from the source
- A secret sync fails to import secrets
- A secret sync fails to remove secrets
- Any other error occurs during the sync process
**Notification includes:**
- Sync name and destination
- The action that failed
- Environment and secret path
- Project name
- Detailed error message explaining the failure
- Direct link to view and troubleshoot the sync configuration
![secret sync error notification](/images/platform/workflow-integrations/slack-integration/secret-sync-error-notification.png)
</Tab>
</Tabs>
Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Some files were not shown because too many files have changed in this diff Show More