mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 19:16:22 +00:00
Added Microsoft ADCS connector
This commit is contained in:
@@ -8,6 +8,7 @@ export enum AppConnection {
|
||||
AzureAppConfiguration = "azure-app-configuration",
|
||||
AzureClientSecrets = "azure-client-secrets",
|
||||
AzureDevOps = "azure-devops",
|
||||
AzureADCS = "azure-adcs",
|
||||
Humanitec = "humanitec",
|
||||
TerraformCloud = "terraform-cloud",
|
||||
Vercel = "vercel",
|
||||
|
||||
@@ -31,6 +31,11 @@ import {
|
||||
} from "./app-connection-types";
|
||||
import { Auth0ConnectionMethod, getAuth0ConnectionListItem, validateAuth0ConnectionCredentials } from "./auth0";
|
||||
import { AwsConnectionMethod, getAwsConnectionListItem, validateAwsConnectionCredentials } from "./aws";
|
||||
import { AzureADCSConnectionMethod } from "./azure-adcs";
|
||||
import {
|
||||
getAzureADCSConnectionListItem,
|
||||
validateAzureADCSConnectionCredentials
|
||||
} from "./azure-adcs/azure-adcs-connection-fns";
|
||||
import {
|
||||
AzureAppConfigurationConnectionMethod,
|
||||
getAzureAppConfigurationConnectionListItem,
|
||||
@@ -136,6 +141,7 @@ export const listAppConnectionOptions = () => {
|
||||
getAzureKeyVaultConnectionListItem(),
|
||||
getAzureAppConfigurationConnectionListItem(),
|
||||
getAzureDevopsConnectionListItem(),
|
||||
getAzureADCSConnectionListItem(),
|
||||
getDatabricksConnectionListItem(),
|
||||
getHumanitecConnectionListItem(),
|
||||
getTerraformCloudConnectionListItem(),
|
||||
@@ -227,6 +233,7 @@ export const validateAppConnectionCredentials = async (
|
||||
[AppConnection.AzureClientSecrets]:
|
||||
validateAzureClientSecretsConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.AzureDevOps]: validateAzureDevOpsConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.AzureADCS]: validateAzureADCSConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.Humanitec]: validateHumanitecConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.Postgres]: validateSqlConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.MsSql]: validateSqlConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
@@ -300,6 +307,7 @@ export const getAppConnectionMethodName = (method: TAppConnection["method"]) =>
|
||||
case MsSqlConnectionMethod.UsernameAndPassword:
|
||||
case MySqlConnectionMethod.UsernameAndPassword:
|
||||
case OracleDBConnectionMethod.UsernameAndPassword:
|
||||
case AzureADCSConnectionMethod.UsernamePassword:
|
||||
return "Username & Password";
|
||||
case WindmillConnectionMethod.AccessToken:
|
||||
case HCVaultConnectionMethod.AccessToken:
|
||||
@@ -357,6 +365,7 @@ export const TRANSITION_CONNECTION_CREDENTIALS_TO_PLATFORM: Record<
|
||||
[AppConnection.AzureKeyVault]: platformManagedCredentialsNotSupported,
|
||||
[AppConnection.AzureAppConfiguration]: platformManagedCredentialsNotSupported,
|
||||
[AppConnection.AzureDevOps]: platformManagedCredentialsNotSupported,
|
||||
[AppConnection.AzureADCS]: platformManagedCredentialsNotSupported,
|
||||
[AppConnection.Humanitec]: platformManagedCredentialsNotSupported,
|
||||
[AppConnection.Postgres]: transferSqlConnectionCredentialsToPlatform as TAppConnectionTransitionCredentialsToPlatform,
|
||||
[AppConnection.MsSql]: transferSqlConnectionCredentialsToPlatform as TAppConnectionTransitionCredentialsToPlatform,
|
||||
|
||||
@@ -9,6 +9,7 @@ export const APP_CONNECTION_NAME_MAP: Record<AppConnection, string> = {
|
||||
[AppConnection.AzureAppConfiguration]: "Azure App Configuration",
|
||||
[AppConnection.AzureClientSecrets]: "Azure Client Secrets",
|
||||
[AppConnection.AzureDevOps]: "Azure DevOps",
|
||||
[AppConnection.AzureADCS]: "Azure ADCS",
|
||||
[AppConnection.Databricks]: "Databricks",
|
||||
[AppConnection.Humanitec]: "Humanitec",
|
||||
[AppConnection.TerraformCloud]: "Terraform Cloud",
|
||||
@@ -49,6 +50,7 @@ export const APP_CONNECTION_PLAN_MAP: Record<AppConnection, AppConnectionPlanTyp
|
||||
[AppConnection.AzureAppConfiguration]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.AzureClientSecrets]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.AzureDevOps]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.AzureADCS]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.Databricks]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.Humanitec]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.TerraformCloud]: AppConnectionPlanType.Regular,
|
||||
|
||||
@@ -45,6 +45,7 @@ import {
|
||||
import { ValidateAuth0ConnectionCredentialsSchema } from "./auth0";
|
||||
import { ValidateAwsConnectionCredentialsSchema } from "./aws";
|
||||
import { awsConnectionService } from "./aws/aws-connection-service";
|
||||
import { ValidateAzureADCSConnectionCredentialsSchema } from "./azure-adcs/azure-adcs-connection-schemas";
|
||||
import { ValidateAzureAppConfigurationConnectionCredentialsSchema } from "./azure-app-configuration";
|
||||
import { ValidateAzureClientSecretsConnectionCredentialsSchema } from "./azure-client-secrets";
|
||||
import { azureClientSecretsConnectionService } from "./azure-client-secrets/azure-client-secrets-service";
|
||||
@@ -122,6 +123,7 @@ const VALIDATE_APP_CONNECTION_CREDENTIALS_MAP: Record<AppConnection, TValidateAp
|
||||
[AppConnection.AzureKeyVault]: ValidateAzureKeyVaultConnectionCredentialsSchema,
|
||||
[AppConnection.AzureAppConfiguration]: ValidateAzureAppConfigurationConnectionCredentialsSchema,
|
||||
[AppConnection.AzureDevOps]: ValidateAzureDevOpsConnectionCredentialsSchema,
|
||||
[AppConnection.AzureADCS]: ValidateAzureADCSConnectionCredentialsSchema,
|
||||
[AppConnection.Databricks]: ValidateDatabricksConnectionCredentialsSchema,
|
||||
[AppConnection.Humanitec]: ValidateHumanitecConnectionCredentialsSchema,
|
||||
[AppConnection.TerraformCloud]: ValidateTerraformCloudConnectionCredentialsSchema,
|
||||
|
||||
@@ -33,6 +33,12 @@ import {
|
||||
TAwsConnectionInput,
|
||||
TValidateAwsConnectionCredentialsSchema
|
||||
} from "./aws";
|
||||
import {
|
||||
TAzureADCSConnection,
|
||||
TAzureADCSConnectionConfig,
|
||||
TAzureADCSConnectionInput,
|
||||
TValidateAzureADCSConnectionCredentialsSchema
|
||||
} from "./azure-adcs/azure-adcs-connection-types";
|
||||
import {
|
||||
TAzureAppConfigurationConnection,
|
||||
TAzureAppConfigurationConnectionConfig,
|
||||
@@ -223,6 +229,7 @@ export type TAppConnection = { id: string } & (
|
||||
| TAzureKeyVaultConnection
|
||||
| TAzureAppConfigurationConnection
|
||||
| TAzureDevOpsConnection
|
||||
| TAzureADCSConnection
|
||||
| TDatabricksConnection
|
||||
| THumanitecConnection
|
||||
| TTerraformCloudConnection
|
||||
@@ -267,6 +274,7 @@ export type TAppConnectionInput = { id: string } & (
|
||||
| TAzureKeyVaultConnectionInput
|
||||
| TAzureAppConfigurationConnectionInput
|
||||
| TAzureDevOpsConnectionInput
|
||||
| TAzureADCSConnectionInput
|
||||
| TDatabricksConnectionInput
|
||||
| THumanitecConnectionInput
|
||||
| TTerraformCloudConnectionInput
|
||||
@@ -322,6 +330,7 @@ export type TAppConnectionConfig =
|
||||
| TAzureKeyVaultConnectionConfig
|
||||
| TAzureAppConfigurationConnectionConfig
|
||||
| TAzureDevOpsConnectionConfig
|
||||
| TAzureADCSConnectionConfig
|
||||
| TAzureClientSecretsConnectionConfig
|
||||
| TDatabricksConnectionConfig
|
||||
| THumanitecConnectionConfig
|
||||
@@ -359,6 +368,7 @@ export type TValidateAppConnectionCredentialsSchema =
|
||||
| TValidateAzureAppConfigurationConnectionCredentialsSchema
|
||||
| TValidateAzureClientSecretsConnectionCredentialsSchema
|
||||
| TValidateAzureDevOpsConnectionCredentialsSchema
|
||||
| TValidateAzureADCSConnectionCredentialsSchema
|
||||
| TValidateDatabricksConnectionCredentialsSchema
|
||||
| TValidateHumanitecConnectionCredentialsSchema
|
||||
| TValidatePostgresConnectionCredentialsSchema
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export enum AzureADCSConnectionMethod {
|
||||
UsernamePassword = "username-password"
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
/* eslint-disable no-case-declarations, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-var-requires, no-await-in-loop, no-continue */
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { decryptAppConnectionCredentials } from "@app/services/app-connection/app-connection-fns";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
|
||||
import { TAppConnectionDALFactory } from "../app-connection-dal";
|
||||
import { AppConnection } from "../app-connection-enums";
|
||||
import { AzureADCSConnectionMethod } from "./azure-adcs-connection-enums";
|
||||
import { TAzureADCSConnectionConfig } from "./azure-adcs-connection-types";
|
||||
|
||||
const httpntlm = require("httpntlm");
|
||||
|
||||
// Type definitions for httpntlm module
|
||||
interface HttpNtlmRequestOptions {
|
||||
url: string;
|
||||
username: string;
|
||||
password: string;
|
||||
domain: string;
|
||||
workstation?: string;
|
||||
method?: string;
|
||||
body?: string;
|
||||
headers?: Record<string, string>;
|
||||
rejectUnauthorized?: boolean;
|
||||
}
|
||||
|
||||
interface HttpNtlmResponse {
|
||||
statusCode: number;
|
||||
body: string;
|
||||
headers: Record<string, string>;
|
||||
}
|
||||
|
||||
// Types for credential parsing
|
||||
interface ParsedCredentials {
|
||||
domain: string;
|
||||
username: string;
|
||||
fullUsername: string; // domain\username format
|
||||
}
|
||||
|
||||
// Helper function to parse and normalize credentials for Windows authentication
|
||||
const parseCredentials = (inputUsername: string): ParsedCredentials => {
|
||||
// Ensure inputUsername is a string
|
||||
if (typeof inputUsername !== "string" || !inputUsername.trim()) {
|
||||
throw new BadRequestError({
|
||||
message: "Username must be a non-empty string"
|
||||
});
|
||||
}
|
||||
|
||||
let domain = "";
|
||||
let username = "";
|
||||
let fullUsername = "";
|
||||
|
||||
if (inputUsername.includes("\\")) {
|
||||
// Already in domain\username format
|
||||
const parts = inputUsername.split("\\");
|
||||
if (parts.length === 2) {
|
||||
[domain, username] = parts;
|
||||
fullUsername = inputUsername;
|
||||
} else {
|
||||
throw new BadRequestError({
|
||||
message: "Invalid domain\\username format. Expected format: DOMAIN\\username"
|
||||
});
|
||||
}
|
||||
} else if (inputUsername.includes("@")) {
|
||||
// UPN format: [email protected]
|
||||
const [user, domainPart] = inputUsername.split("@");
|
||||
if (!user || !domainPart) {
|
||||
throw new BadRequestError({
|
||||
message: "Invalid UPN format. Expected format: [email protected]"
|
||||
});
|
||||
}
|
||||
|
||||
username = user;
|
||||
// Extract NetBIOS name from FQDN
|
||||
domain = domainPart.split(".")[0].toUpperCase();
|
||||
fullUsername = `${domain}\\${username}`;
|
||||
} else {
|
||||
// Plain username - assume local account or current domain
|
||||
username = inputUsername;
|
||||
domain = "";
|
||||
fullUsername = inputUsername;
|
||||
}
|
||||
|
||||
return { domain, username, fullUsername };
|
||||
};
|
||||
|
||||
// Helper to normalize URL
|
||||
const normalizeAdcsUrl = (url: string): string => {
|
||||
let normalizedUrl = url.trim();
|
||||
|
||||
// Remove trailing slash
|
||||
normalizedUrl = normalizedUrl.replace(/\/$/, "");
|
||||
|
||||
// Ensure HTTPS protocol
|
||||
if (normalizedUrl.startsWith("http://")) {
|
||||
normalizedUrl = normalizedUrl.replace("http://", "https://");
|
||||
} else if (!normalizedUrl.startsWith("https://")) {
|
||||
normalizedUrl = `https://${normalizedUrl}`;
|
||||
}
|
||||
|
||||
return normalizedUrl;
|
||||
};
|
||||
|
||||
// NTLM request wrapper
|
||||
const ntlmRequest = (options: HttpNtlmRequestOptions): Promise<HttpNtlmResponse> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const method = options.method || "GET";
|
||||
|
||||
if (method.toLowerCase() === "get") {
|
||||
httpntlm.get(options, (err: Error | null, res: HttpNtlmResponse) => {
|
||||
if (err) reject(err);
|
||||
else resolve(res);
|
||||
});
|
||||
} else if (method.toLowerCase() === "post") {
|
||||
httpntlm.post(options, (err: Error | null, res: HttpNtlmResponse) => {
|
||||
if (err) reject(err);
|
||||
else resolve(res);
|
||||
});
|
||||
} else {
|
||||
reject(new Error(`Unsupported HTTP method: ${method}`));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Test ADCS connectivity and authentication using NTLM
|
||||
const testAdcsConnection = async (
|
||||
credentials: ParsedCredentials,
|
||||
password: string,
|
||||
baseUrl: string
|
||||
): Promise<boolean> => {
|
||||
// Test endpoints in order of preference
|
||||
const testEndpoints = [
|
||||
"/certsrv/certrqus.asp", // Certificate request status (most reliable)
|
||||
"/certsrv/certfnsh.asp", // Certificate finalization
|
||||
"/certsrv/default.asp", // Main ADCS page
|
||||
"/certsrv/" // Root certsrv
|
||||
];
|
||||
|
||||
for (const endpoint of testEndpoints) {
|
||||
try {
|
||||
const testUrl = `${baseUrl}${endpoint}`;
|
||||
|
||||
const response = await ntlmRequest({
|
||||
url: testUrl,
|
||||
username: credentials.username,
|
||||
password,
|
||||
domain: credentials.domain,
|
||||
workstation: "",
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
|
||||
// Check if we got a successful response
|
||||
if (response.statusCode === 200) {
|
||||
const responseText = response.body;
|
||||
|
||||
// Verify this is actually an ADCS server by checking content
|
||||
const adcsIndicators = [
|
||||
"Microsoft Active Directory Certificate Services",
|
||||
"Certificate Services",
|
||||
"Request a certificate",
|
||||
"certsrv",
|
||||
"Certificate Template",
|
||||
"Web Enrollment"
|
||||
];
|
||||
|
||||
const isAdcsServer = adcsIndicators.some((indicator) =>
|
||||
responseText.toLowerCase().includes(indicator.toLowerCase())
|
||||
);
|
||||
|
||||
if (isAdcsServer) {
|
||||
// Successfully authenticated and confirmed ADCS
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle authentication failures
|
||||
if (response.statusCode === 401) {
|
||||
throw new BadRequestError({
|
||||
message: "Authentication failed. Please verify your username, password, and domain are correct."
|
||||
});
|
||||
}
|
||||
|
||||
if (response.statusCode === 403) {
|
||||
throw new BadRequestError({
|
||||
message: "Access denied. Your account may not have permission to access ADCS web enrollment."
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof BadRequestError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Handle network and connection errors
|
||||
if (error instanceof Error) {
|
||||
if (error.message.includes("ENOTFOUND")) {
|
||||
throw new BadRequestError({
|
||||
message: "Cannot resolve ADCS server hostname. Please verify the URL is correct."
|
||||
});
|
||||
}
|
||||
if (error.message.includes("ECONNREFUSED")) {
|
||||
throw new BadRequestError({
|
||||
message: "Connection refused by ADCS server. Please verify the server is running and accessible."
|
||||
});
|
||||
}
|
||||
if (error.message.includes("ETIMEDOUT")) {
|
||||
throw new BadRequestError({
|
||||
message: "Connection timeout. Please verify the server is accessible and not blocked by firewall."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Continue to next endpoint for other errors
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, no endpoint worked
|
||||
throw new BadRequestError({
|
||||
message: "Could not connect to ADCS server. Please verify the server URL and that Web Enrollment is enabled."
|
||||
});
|
||||
};
|
||||
|
||||
// Create authenticated NTLM client for ADCS operations
|
||||
const createNtlmClient = (username: string, password: string, baseUrl: string) => {
|
||||
const parsedCredentials = parseCredentials(username);
|
||||
const normalizedUrl = normalizeAdcsUrl(baseUrl);
|
||||
|
||||
return {
|
||||
get: (endpoint: string, additionalOptions: Partial<HttpNtlmRequestOptions> = {}) => {
|
||||
return ntlmRequest({
|
||||
url: `${normalizedUrl}${endpoint}`,
|
||||
username: parsedCredentials.username,
|
||||
password,
|
||||
domain: parsedCredentials.domain,
|
||||
workstation: "",
|
||||
rejectUnauthorized: false,
|
||||
...additionalOptions
|
||||
});
|
||||
},
|
||||
post: (endpoint: string, body: string, additionalOptions: Partial<HttpNtlmRequestOptions> = {}) => {
|
||||
return ntlmRequest({
|
||||
method: "POST",
|
||||
url: `${normalizedUrl}${endpoint}`,
|
||||
username: parsedCredentials.username,
|
||||
password,
|
||||
domain: parsedCredentials.domain,
|
||||
workstation: "",
|
||||
rejectUnauthorized: false,
|
||||
body,
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
...additionalOptions.headers
|
||||
},
|
||||
...additionalOptions
|
||||
});
|
||||
},
|
||||
baseUrl: normalizedUrl,
|
||||
credentials: parsedCredentials
|
||||
};
|
||||
};
|
||||
|
||||
export const getAzureADCSConnectionCredentials = async (
|
||||
connectionId: string,
|
||||
appConnectionDAL: Pick<TAppConnectionDALFactory, "findById">,
|
||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">
|
||||
) => {
|
||||
const appConnection = await appConnectionDAL.findById(connectionId);
|
||||
|
||||
if (!appConnection) {
|
||||
throw new NotFoundError({ message: `Connection with ID '${connectionId}' not found` });
|
||||
}
|
||||
|
||||
if (appConnection.app !== AppConnection.AzureADCS) {
|
||||
throw new BadRequestError({ message: `Connection with ID '${connectionId}' is not an Azure ADCS connection` });
|
||||
}
|
||||
|
||||
switch (appConnection.method) {
|
||||
case AzureADCSConnectionMethod.UsernamePassword:
|
||||
const credentials = (await decryptAppConnectionCredentials({
|
||||
orgId: appConnection.orgId,
|
||||
kmsService,
|
||||
encryptedCredentials: appConnection.encryptedCredentials
|
||||
})) as { username: string; password: string; adcsUrl: string };
|
||||
|
||||
return {
|
||||
username: credentials.username,
|
||||
password: credentials.password,
|
||||
adcsUrl: credentials.adcsUrl
|
||||
};
|
||||
|
||||
default:
|
||||
throw new BadRequestError({
|
||||
message: `Unsupported Azure ADCS connection method: ${appConnection.method}`
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const validateAzureADCSConnectionCredentials = async (appConnection: TAzureADCSConnectionConfig) => {
|
||||
const { credentials } = appConnection;
|
||||
|
||||
try {
|
||||
// Parse and validate credentials
|
||||
const parsedCredentials = parseCredentials(credentials.username);
|
||||
const normalizedUrl = normalizeAdcsUrl(credentials.adcsUrl);
|
||||
|
||||
// Test the connection using NTLM
|
||||
await testAdcsConnection(parsedCredentials, credentials.password, normalizedUrl);
|
||||
|
||||
// If we get here, authentication was successful
|
||||
return {
|
||||
username: credentials.username,
|
||||
password: credentials.password,
|
||||
adcsUrl: credentials.adcsUrl
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof BadRequestError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Handle unexpected errors
|
||||
let errorMessage = "Unable to validate ADCS connection.";
|
||||
if (error instanceof Error) {
|
||||
if (error.message.includes("401") || error.message.includes("Unauthorized")) {
|
||||
errorMessage = "NTLM authentication failed. Please verify your username, password, and domain are correct.";
|
||||
} else if (error.message.includes("ENOTFOUND") || error.message.includes("ECONNREFUSED")) {
|
||||
errorMessage = "Cannot connect to the ADCS server. Please verify the server URL is correct and accessible.";
|
||||
} else if (error.message.includes("timeout")) {
|
||||
errorMessage = "Connection to ADCS server timed out. Please verify the server is accessible.";
|
||||
} else if (
|
||||
error.message.includes("certificate") ||
|
||||
error.message.includes("SSL") ||
|
||||
error.message.includes("TLS")
|
||||
) {
|
||||
errorMessage = "SSL/TLS certificate error. The server certificate may be self-signed or invalid.";
|
||||
}
|
||||
}
|
||||
|
||||
throw new BadRequestError({
|
||||
message: `Failed to validate Azure ADCS connection: ${errorMessage} Details: ${
|
||||
error instanceof Error ? error.message : "Unknown error"
|
||||
}`
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getAzureADCSConnectionListItem = () => ({
|
||||
name: "Azure ADCS" as const,
|
||||
app: AppConnection.AzureADCS as const,
|
||||
methods: [AzureADCSConnectionMethod.UsernamePassword] as [AzureADCSConnectionMethod.UsernamePassword]
|
||||
});
|
||||
|
||||
// Export helper functions for use in certificate ordering
|
||||
export const createAdcsHttpClient = (username: string, password: string, baseUrl: string) => {
|
||||
return createNtlmClient(username, password, baseUrl);
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
import z from "zod";
|
||||
|
||||
import { AppConnections } from "@app/lib/api-docs";
|
||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||
import {
|
||||
BaseAppConnectionSchema,
|
||||
GenericCreateAppConnectionFieldsSchema,
|
||||
GenericUpdateAppConnectionFieldsSchema
|
||||
} from "@app/services/app-connection/app-connection-schemas";
|
||||
|
||||
import { AzureADCSConnectionMethod } from "./azure-adcs-connection-enums";
|
||||
|
||||
export const AzureADCSConnectionAccessTokenCredentialsSchema = z.object({
|
||||
adcsUrl: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "ADCS URL required")
|
||||
.max(255)
|
||||
.describe(AppConnections.CREDENTIALS.AZURE_ADCS.adcsUrl),
|
||||
username: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "Username required")
|
||||
.max(255)
|
||||
.describe(AppConnections.CREDENTIALS.AZURE_ADCS.username),
|
||||
password: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "Password required")
|
||||
.max(255)
|
||||
.describe(AppConnections.CREDENTIALS.AZURE_ADCS.password)
|
||||
});
|
||||
|
||||
const BaseAzureADCSConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.AzureADCS) });
|
||||
|
||||
export const AzureADCSConnectionSchema = BaseAzureADCSConnectionSchema.extend({
|
||||
method: z.literal(AzureADCSConnectionMethod.UsernamePassword),
|
||||
credentials: AzureADCSConnectionAccessTokenCredentialsSchema
|
||||
});
|
||||
|
||||
export const SanitizedAzureADCSConnectionSchema = z.discriminatedUnion("method", [
|
||||
BaseAzureADCSConnectionSchema.extend({
|
||||
method: z.literal(AzureADCSConnectionMethod.UsernamePassword),
|
||||
credentials: AzureADCSConnectionAccessTokenCredentialsSchema.pick({
|
||||
username: true
|
||||
})
|
||||
})
|
||||
]);
|
||||
|
||||
export const ValidateAzureADCSConnectionCredentialsSchema = z.discriminatedUnion("method", [
|
||||
z.object({
|
||||
method: z
|
||||
.literal(AzureADCSConnectionMethod.UsernamePassword)
|
||||
.describe(AppConnections.CREATE(AppConnection.AzureADCS).method),
|
||||
credentials: AzureADCSConnectionAccessTokenCredentialsSchema.describe(
|
||||
AppConnections.CREATE(AppConnection.AzureADCS).credentials
|
||||
)
|
||||
})
|
||||
]);
|
||||
|
||||
export const CreateAzureADCSConnectionSchema = ValidateAzureADCSConnectionCredentialsSchema.and(
|
||||
GenericCreateAppConnectionFieldsSchema(AppConnection.AzureADCS)
|
||||
);
|
||||
|
||||
export const UpdateAzureADCSConnectionSchema = z
|
||||
.object({
|
||||
credentials: AzureADCSConnectionAccessTokenCredentialsSchema.optional().describe(
|
||||
AppConnections.UPDATE(AppConnection.AzureADCS).credentials
|
||||
)
|
||||
})
|
||||
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.AzureADCS));
|
||||
|
||||
export const AzureADCSConnectionListItemSchema = z.object({
|
||||
name: z.literal("Azure ADCS"),
|
||||
app: z.literal(AppConnection.AzureADCS),
|
||||
methods: z.nativeEnum(AzureADCSConnectionMethod).array()
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import z from "zod";
|
||||
|
||||
import { DiscriminativePick } from "@app/lib/types";
|
||||
|
||||
import { AppConnection } from "../app-connection-enums";
|
||||
import {
|
||||
AzureADCSConnectionSchema,
|
||||
CreateAzureADCSConnectionSchema,
|
||||
ValidateAzureADCSConnectionCredentialsSchema
|
||||
} from "./azure-adcs-connection-schemas";
|
||||
|
||||
export type TAzureADCSConnection = z.infer<typeof AzureADCSConnectionSchema>;
|
||||
|
||||
export type TAzureADCSConnectionInput = z.infer<typeof CreateAzureADCSConnectionSchema> & {
|
||||
app: AppConnection.AzureADCS;
|
||||
};
|
||||
|
||||
export type TValidateAzureADCSConnectionCredentialsSchema = typeof ValidateAzureADCSConnectionCredentialsSchema;
|
||||
|
||||
export type TAzureADCSConnectionConfig = DiscriminativePick<
|
||||
TAzureADCSConnectionInput,
|
||||
"method" | "app" | "credentials"
|
||||
>;
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from "./azure-adcs-connection-enums";
|
||||
export * from "./azure-adcs-connection-fns";
|
||||
export * from "./azure-adcs-connection-schemas";
|
||||
export * from "./azure-adcs-connection-types";
|
||||
Reference in New Issue
Block a user