mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
review fixes
This commit is contained in:
@@ -3,6 +3,7 @@ import { AxiosError } from "axios";
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { removeTrailingSlash } from "@app/lib/fn";
|
||||
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||
|
||||
import { TeamCityConnectionMethod } from "./teamcity-connection-enums";
|
||||
@@ -12,6 +13,14 @@ import {
|
||||
TTeamCityListProjectsResponse
|
||||
} from "./teamcity-connection-types";
|
||||
|
||||
export const getTeamCityInstanceUrl = async (config: TTeamCityConnectionConfig) => {
|
||||
const instanceUrl = removeTrailingSlash(config.credentials.instanceUrl);
|
||||
|
||||
await blockLocalAndPrivateIpAddresses(instanceUrl);
|
||||
|
||||
return instanceUrl;
|
||||
};
|
||||
|
||||
export const getTeamCityConnectionListItem = () => {
|
||||
return {
|
||||
name: "TeamCity" as const,
|
||||
@@ -21,7 +30,8 @@ export const getTeamCityConnectionListItem = () => {
|
||||
};
|
||||
|
||||
export const validateTeamCityConnectionCredentials = async (config: TTeamCityConnectionConfig) => {
|
||||
const instanceUrl = removeTrailingSlash(config.credentials.instanceUrl);
|
||||
const instanceUrl = await getTeamCityInstanceUrl(config);
|
||||
|
||||
const { accessToken } = config.credentials;
|
||||
|
||||
try {
|
||||
@@ -46,7 +56,7 @@ export const validateTeamCityConnectionCredentials = async (config: TTeamCityCon
|
||||
};
|
||||
|
||||
export const listTeamCityProjects = async (appConnection: TTeamCityConnection) => {
|
||||
const instanceUrl = removeTrailingSlash(appConnection.credentials.instanceUrl);
|
||||
const instanceUrl = await getTeamCityInstanceUrl(appConnection);
|
||||
const { accessToken } = appConnection.credentials;
|
||||
|
||||
const resp = await request.get<TTeamCityListProjectsResponse>(
|
||||
|
||||
@@ -145,7 +145,9 @@ export const SecretSyncFns = {
|
||||
case SecretSync.TeamCity:
|
||||
return TeamCitySyncFns.syncSecrets(secretSync, secretMap);
|
||||
default:
|
||||
throw new Error(`Unhandled sync destination for sync secrets fns: ${secretSync.destination}`);
|
||||
throw new Error(
|
||||
`Unhandled sync destination for sync secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}`
|
||||
);
|
||||
}
|
||||
},
|
||||
getSecrets: async (
|
||||
@@ -205,7 +207,9 @@ export const SecretSyncFns = {
|
||||
secretMap = await TeamCitySyncFns.getSecrets(secretSync);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unhandled sync destination for get secrets fns: ${secretSync.destination}`);
|
||||
throw new Error(
|
||||
`Unhandled sync destination for get secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}`
|
||||
);
|
||||
}
|
||||
|
||||
return secretMap;
|
||||
@@ -258,7 +262,9 @@ export const SecretSyncFns = {
|
||||
case SecretSync.TeamCity:
|
||||
return TeamCitySyncFns.removeSecrets(secretSync, secretMap);
|
||||
default:
|
||||
throw new Error(`Unhandled sync destination for remove secrets fns: ${secretSync.destination}`);
|
||||
throw new Error(
|
||||
`Unhandled sync destination for remove secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}`
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { removeTrailingSlash } from "@app/lib/fn";
|
||||
import { getTeamCityInstanceUrl } from "@app/services/app-connection/teamcity";
|
||||
import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors";
|
||||
import { TSecretMap } from "@app/services/secret-sync/secret-sync-types";
|
||||
import {
|
||||
@@ -89,7 +89,7 @@ export const TeamCitySyncFns = {
|
||||
destinationConfig: { project, buildConfig }
|
||||
} = secretSync;
|
||||
|
||||
const instanceUrl = removeTrailingSlash(connection.credentials.instanceUrl);
|
||||
const instanceUrl = await getTeamCityInstanceUrl(connection);
|
||||
const { accessToken } = connection.credentials;
|
||||
|
||||
for await (const entry of Object.entries(secretMap)) {
|
||||
@@ -145,7 +145,7 @@ export const TeamCitySyncFns = {
|
||||
destinationConfig: { project, buildConfig }
|
||||
} = secretSync;
|
||||
|
||||
const instanceUrl = removeTrailingSlash(connection.credentials.instanceUrl);
|
||||
const instanceUrl = await getTeamCityInstanceUrl(connection);
|
||||
const { accessToken } = connection.credentials;
|
||||
|
||||
const variables = await listTeamCityVariables({ instanceUrl, accessToken, project, buildConfig });
|
||||
@@ -175,7 +175,7 @@ export const TeamCitySyncFns = {
|
||||
destinationConfig: { project, buildConfig }
|
||||
} = secretSync;
|
||||
|
||||
const instanceUrl = removeTrailingSlash(connection.credentials.instanceUrl);
|
||||
const instanceUrl = await getTeamCityInstanceUrl(connection);
|
||||
const { accessToken } = connection.credentials;
|
||||
|
||||
return listTeamCityVariables({ instanceUrl, accessToken, project, buildConfig });
|
||||
|
||||
@@ -18,17 +18,28 @@ Infisical supports connecting to TeamCity using an Access Token to securely sync
|
||||
</Step>
|
||||
<Step title="Create the Access Token">
|
||||
Click the **Create access token** button and provide a name for your token (e.g., "Infisical Integration"). You may set an expiration date or leave it blank for no expiry.
|
||||
The permission scope can either be **Same as current user** or **Limit per project**. If you're choosing **Limit per project**, make sure you select the relevant project and enable the **View build configuration settings** and **Edit project** permissions.
|
||||
The permission scope can either be **Same as current user** or **Limit per project**.
|
||||
|
||||
If you're choosing **Limit per project**, make sure you select the relevant project and enable the permissions relevant to your use case:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Secret Sync Permissions">
|
||||
- View build configuration settings
|
||||
- Edit project
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||

|
||||
|
||||
<Note>
|
||||
Setting your permission scope to **Same as current user** will allow your integration to access multiple projects as long as the current user has read and write access to them.
|
||||
</Note>
|
||||
<Note>
|
||||
Setting your permission scope to **Limit per project** requires the **View build configuration settings** and **Edit project** permissions.
|
||||
If you configure an expiry date for your access token, you must manually rotate to a new token before the expiration date to prevent service interruption.
|
||||
</Note>
|
||||

|
||||
</Step>
|
||||
<Step title="Copy the Access Token">
|
||||
After creation, a modal with the API token will be displayed. Copy this token immediately and store it securely, as you won't be able to view it again after closing this dialog.
|
||||
After creation, a modal with the Access Token will be displayed. Copy this token immediately and store it securely, as you won't be able to view it again after closing this dialog.
|
||||

|
||||
</Step>
|
||||
<Step title="Token Created">
|
||||
|
||||
@@ -434,10 +434,10 @@
|
||||
"integrations/app-connections/humanitec",
|
||||
"integrations/app-connections/mssql",
|
||||
"integrations/app-connections/postgres",
|
||||
"integrations/app-connections/teamcity",
|
||||
"integrations/app-connections/terraform-cloud",
|
||||
"integrations/app-connections/vercel",
|
||||
"integrations/app-connections/windmill",
|
||||
"integrations/app-connections/teamcity"
|
||||
"integrations/app-connections/windmill"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -458,10 +458,10 @@
|
||||
"integrations/secret-syncs/gcp-secret-manager",
|
||||
"integrations/secret-syncs/github",
|
||||
"integrations/secret-syncs/humanitec",
|
||||
"integrations/secret-syncs/teamcity",
|
||||
"integrations/secret-syncs/terraform-cloud",
|
||||
"integrations/secret-syncs/vercel",
|
||||
"integrations/secret-syncs/windmill",
|
||||
"integrations/secret-syncs/teamcity"
|
||||
"integrations/secret-syncs/windmill"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1045,6 +1045,18 @@
|
||||
"api-reference/endpoints/app-connections/postgres/delete"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "TeamCity",
|
||||
"pages": [
|
||||
"api-reference/endpoints/app-connections/teamcity/list",
|
||||
"api-reference/endpoints/app-connections/teamcity/available",
|
||||
"api-reference/endpoints/app-connections/teamcity/get-by-id",
|
||||
"api-reference/endpoints/app-connections/teamcity/get-by-name",
|
||||
"api-reference/endpoints/app-connections/teamcity/create",
|
||||
"api-reference/endpoints/app-connections/teamcity/update",
|
||||
"api-reference/endpoints/app-connections/teamcity/delete"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Terraform Cloud",
|
||||
"pages": [
|
||||
@@ -1080,18 +1092,6 @@
|
||||
"api-reference/endpoints/app-connections/windmill/update",
|
||||
"api-reference/endpoints/app-connections/windmill/delete"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "TeamCity",
|
||||
"pages": [
|
||||
"api-reference/endpoints/app-connections/teamcity/list",
|
||||
"api-reference/endpoints/app-connections/teamcity/available",
|
||||
"api-reference/endpoints/app-connections/teamcity/get-by-id",
|
||||
"api-reference/endpoints/app-connections/teamcity/get-by-name",
|
||||
"api-reference/endpoints/app-connections/teamcity/create",
|
||||
"api-reference/endpoints/app-connections/teamcity/update",
|
||||
"api-reference/endpoints/app-connections/teamcity/delete"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1222,6 +1222,20 @@
|
||||
"api-reference/endpoints/secret-syncs/humanitec/remove-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "TeamCity",
|
||||
"pages": [
|
||||
"api-reference/endpoints/secret-syncs/teamcity/list",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/get-by-id",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/get-by-name",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/create",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/update",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/delete",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/sync-secrets",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/import-secrets",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/remove-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Terraform Cloud",
|
||||
"pages": [
|
||||
@@ -1262,20 +1276,6 @@
|
||||
"api-reference/endpoints/secret-syncs/windmill/import-secrets",
|
||||
"api-reference/endpoints/secret-syncs/windmill/remove-secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "TeamCity",
|
||||
"pages": [
|
||||
"api-reference/endpoints/secret-syncs/teamcity/list",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/get-by-id",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/get-by-name",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/create",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/update",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/delete",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/sync-secrets",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/import-secrets",
|
||||
"api-reference/endpoints/secret-syncs/teamcity/remove-secrets"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -90,9 +90,15 @@ export const TeamCitySyncFields = () => {
|
||||
isOptional
|
||||
label="Build Configuration"
|
||||
helperText={
|
||||
<span>
|
||||
Not selecting a Build Configuration will sync your secrets with the entire project.
|
||||
</span>
|
||||
<Tooltip
|
||||
className="max-w-md"
|
||||
content='Ensure the configuration exists in the selected project and that your Access Token has the "View build configuration settings" permission.'
|
||||
>
|
||||
<div>
|
||||
<span>Don't see the configuration you're looking for?</span>{" "}
|
||||
<FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-400" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
<FilterableSelect
|
||||
@@ -113,6 +119,10 @@ export const TeamCitySyncFields = () => {
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<span className="text-sm text-bunker-300">
|
||||
Not selecting a Build Configuration will sync your secrets to the entire project.
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,6 +9,6 @@ export type TTeamCityConnection = TRootAppConnection & { app: AppConnection.Team
|
||||
method: TeamCityConnectionMethod.AccessToken;
|
||||
credentials: {
|
||||
accessToken: string;
|
||||
instanceUrl?: string;
|
||||
instanceUrl: string;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -34,14 +34,7 @@ const formSchema = z.discriminatedUnion("method", [
|
||||
method: z.literal(TeamCityConnectionMethod.AccessToken),
|
||||
credentials: z.object({
|
||||
accessToken: z.string().trim().min(1, "Access Token required"),
|
||||
instanceUrl: z
|
||||
.string()
|
||||
.trim()
|
||||
.transform((value) => value || undefined)
|
||||
.refine((value) => (!value ? true : z.string().url().safeParse(value).success), {
|
||||
message: "Invalid instance URL"
|
||||
})
|
||||
.optional()
|
||||
instanceUrl: z.string().trim().url("Invalid Instance URL")
|
||||
})
|
||||
})
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user