mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-08 23:18:05 -05:00
fix: migrate heroku oauth connection to new oauth connection format
This commit is contained in:
@@ -122,7 +122,7 @@ INF_APP_CONNECTION_GITHUB_RADAR_APP_WEBHOOK_SECRET=
|
||||
#gcp app connection
|
||||
INF_APP_CONNECTION_GCP_SERVICE_ACCOUNT_CREDENTIAL=
|
||||
|
||||
# azure app connection
|
||||
# azure app connections
|
||||
INF_APP_CONNECTION_AZURE_APP_CONFIGURATION_CLIENT_ID=
|
||||
INF_APP_CONNECTION_AZURE_APP_CONFIGURATION_CLIENT_SECRET=
|
||||
|
||||
@@ -135,6 +135,10 @@ INF_APP_CONNECTION_AZURE_CLIENT_SECRETS_CLIENT_SECRET=
|
||||
INF_APP_CONNECTION_AZURE_DEVOPS_CLIENT_ID=
|
||||
INF_APP_CONNECTION_AZURE_DEVOPS_CLIENT_SECRET=
|
||||
|
||||
# heroku app connection
|
||||
INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_ID=
|
||||
INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_SECRET=
|
||||
|
||||
# datadog
|
||||
SHOULD_USE_DATADOG_TRACER=
|
||||
DATADOG_PROFILING_ENABLED=
|
||||
|
||||
@@ -323,6 +323,10 @@ const envSchema = z
|
||||
INF_APP_CONNECTION_AZURE_DEVOPS_CLIENT_ID: zpStr(z.string().optional()),
|
||||
INF_APP_CONNECTION_AZURE_DEVOPS_CLIENT_SECRET: zpStr(z.string().optional()),
|
||||
|
||||
// Heroku App Connection
|
||||
INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_ID: zpStr(z.string().optional()),
|
||||
INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_SECRET: zpStr(z.string().optional()),
|
||||
|
||||
// datadog
|
||||
SHOULD_USE_DATADOG_TRACER: zodStrBool.default("false"),
|
||||
DATADOG_PROFILING_ENABLED: zodStrBool.default("false"),
|
||||
@@ -736,6 +740,19 @@ export const overwriteSchema: {
|
||||
description: "The Client Secret of your GCP OAuth2 application."
|
||||
}
|
||||
]
|
||||
},
|
||||
heroku: {
|
||||
name: "Heroku",
|
||||
fields: [
|
||||
{
|
||||
key: "INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_ID",
|
||||
description: "The Client ID of your Heroku application."
|
||||
},
|
||||
{
|
||||
key: "INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_SECRET",
|
||||
description: "The Client Secret of your Heroku application."
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,13 +22,13 @@ interface HerokuOAuthTokenResponse {
|
||||
}
|
||||
|
||||
export const getHerokuConnectionListItem = () => {
|
||||
const { CLIENT_ID_HEROKU } = getConfig();
|
||||
const { INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_ID } = getConfig();
|
||||
|
||||
return {
|
||||
name: "Heroku" as const,
|
||||
app: AppConnection.Heroku as const,
|
||||
methods: Object.values(HerokuConnectionMethod) as [HerokuConnectionMethod.AuthToken, HerokuConnectionMethod.OAuth],
|
||||
oauthClientId: CLIENT_ID_HEROKU
|
||||
oauthClientId: INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_ID
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 459 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 425 KiB |
@@ -24,7 +24,7 @@ Infisical supports two methods for connecting to Heroku: **OAuth** and **Auth To
|
||||

|
||||

|
||||
|
||||
Create the API client. As part of the form, set the **OAuth callback URL** to `https://your-domain.com/integrations/heroku/oauth2/callback`.
|
||||
Create the API client. As part of the form, set the **OAuth callback URL** to `https://your-domain.com/organization/app-connections/heroku/oauth/callback`.
|
||||
|
||||
<Tip>
|
||||
The domain you defined in the OAuth callback URL should be equivalent to the `SITE_URL` configured in your Infisical instance.
|
||||
@@ -39,8 +39,8 @@ Infisical supports two methods for connecting to Heroku: **OAuth** and **Auth To
|
||||
|
||||
Back in your Infisical instance, add two new environment variables for the credentials of your Heroku API client:
|
||||
|
||||
- `CLIENT_ID_HEROKU`: The **Client ID** of your Heroku API client.
|
||||
- `CLIENT_SECRET_HEROKU`: The **Client Secret** of your Heroku API client.
|
||||
- `INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_ID`: The **Client ID** of your Heroku API client.
|
||||
- `INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_SECRET`: The **Client Secret** of your Heroku API client.
|
||||
|
||||
Once added, restart your Infisical instance and use the Heroku Connection.
|
||||
</Step>
|
||||
|
||||
@@ -672,6 +672,16 @@ You can configure third-party app connections for re-use across Infisical Projec
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Heroku OAuth Connection">
|
||||
<ParamField query="INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_ID" type="string" default="none" optional>
|
||||
The Application ID of your Heroku OAuth application.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_SECRET" type="string" default="none" optional>
|
||||
The Secret of your GitLab Heroku OAuth application.
|
||||
</ParamField>
|
||||
</Accordion>
|
||||
|
||||
## Native Secret Integrations
|
||||
|
||||
To help you sync secrets from Infisical to services such as Github and Gitlab, Infisical provides native integrations out of the box.
|
||||
|
||||
@@ -142,7 +142,7 @@ const CreateForm = ({ app, onComplete, projectId }: CreateFormProps) => {
|
||||
case AppConnection.OnePass:
|
||||
return <OnePassConnectionForm onSubmit={onSubmit} />;
|
||||
case AppConnection.Heroku:
|
||||
return <HerokuConnectionForm onSubmit={onSubmit} />;
|
||||
return <HerokuConnectionForm onSubmit={onSubmit} projectId={projectId} />;
|
||||
case AppConnection.Render:
|
||||
return <RenderConnectionForm onSubmit={onSubmit} />;
|
||||
case AppConnection.Flyio:
|
||||
@@ -285,7 +285,13 @@ const UpdateForm = ({ appConnection, onComplete }: UpdateFormProps) => {
|
||||
case AppConnection.OnePass:
|
||||
return <OnePassConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
|
||||
case AppConnection.Heroku:
|
||||
return <HerokuConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
|
||||
return (
|
||||
<HerokuConnectionForm
|
||||
onSubmit={onSubmit}
|
||||
appConnection={appConnection}
|
||||
projectId={appConnection.projectId}
|
||||
/>
|
||||
);
|
||||
case AppConnection.Render:
|
||||
return <RenderConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
|
||||
case AppConnection.Flyio:
|
||||
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
} from "@app/hooks/api/appConnections";
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
|
||||
import { GithubFormData } from "../../../OauthCallbackPage/OauthCallbackPage.types";
|
||||
import { GitHubFormData } from "../../../OauthCallbackPage/OauthCallbackPage.types";
|
||||
import {
|
||||
genericAppConnectionFieldsSchema,
|
||||
GenericAppConnectionsFields
|
||||
@@ -118,7 +118,7 @@ export const GitHubConnectionForm = ({ appConnection, projectId }: Props) => {
|
||||
connectionId: appConnection?.id,
|
||||
projectId,
|
||||
returnUrl
|
||||
} as GithubFormData)
|
||||
} as GitHubFormData)
|
||||
);
|
||||
|
||||
const githubHost =
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
} from "@app/hooks/api/appConnections";
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
|
||||
import { GithubRadarFormData } from "../../../OauthCallbackPage/OauthCallbackPage.types";
|
||||
import { GitHubRadarFormData } from "../../../OauthCallbackPage/OauthCallbackPage.types";
|
||||
import {
|
||||
genericAppConnectionFieldsSchema,
|
||||
GenericAppConnectionsFields
|
||||
@@ -76,7 +76,7 @@ export const GitHubRadarConnectionForm = ({ appConnection, projectId }: Props) =
|
||||
connectionId: appConnection?.id,
|
||||
projectId,
|
||||
returnUrl
|
||||
} as GithubRadarFormData)
|
||||
} as GitHubRadarFormData)
|
||||
);
|
||||
|
||||
switch (formData.method) {
|
||||
|
||||
@@ -15,7 +15,11 @@ import {
|
||||
Select,
|
||||
SelectItem
|
||||
} from "@app/components/v2";
|
||||
import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections";
|
||||
import {
|
||||
APP_CONNECTION_MAP,
|
||||
getAppConnectionMethodDetails,
|
||||
useGetAppConnectionOauthReturnUrl
|
||||
} from "@app/helpers/appConnections";
|
||||
import { isInfisicalCloud } from "@app/helpers/platform";
|
||||
import { useGetAppConnectionOption } from "@app/hooks/api/appConnections";
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
@@ -32,6 +36,7 @@ import {
|
||||
type Props = {
|
||||
appConnection?: THerokuConnection;
|
||||
onSubmit: (formData: FormData) => Promise<void>;
|
||||
projectId: string | undefined | null;
|
||||
};
|
||||
|
||||
const formSchema = z.discriminatedUnion("method", [
|
||||
@@ -53,10 +58,12 @@ const formSchema = z.discriminatedUnion("method", [
|
||||
|
||||
type FormData = z.infer<typeof formSchema>;
|
||||
|
||||
export const HerokuConnectionForm = ({ appConnection, onSubmit: formSubmit }: Props) => {
|
||||
export const HerokuConnectionForm = ({ appConnection, onSubmit: formSubmit, projectId }: Props) => {
|
||||
const isUpdate = Boolean(appConnection);
|
||||
const [isRedirecting, setIsRedirecting] = useState(false);
|
||||
|
||||
const returnUrl = useGetAppConnectionOauthReturnUrl();
|
||||
|
||||
const {
|
||||
option: { oauthClientId },
|
||||
isLoading
|
||||
@@ -110,7 +117,8 @@ export const HerokuConnectionForm = ({ appConnection, onSubmit: formSubmit }: Pr
|
||||
JSON.stringify({
|
||||
...formData,
|
||||
connectionId: appConnection?.id,
|
||||
isUpdate
|
||||
returnUrl,
|
||||
projectId
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
AzureKeyVaultConnectionMethod,
|
||||
GitHubConnectionMethod,
|
||||
GitLabConnectionMethod,
|
||||
HerokuConnectionMethod,
|
||||
TAppConnection,
|
||||
useCreateAppConnection,
|
||||
useUpdateAppConnection
|
||||
@@ -28,7 +29,8 @@ const formDataStorageFieldMap: Partial<Record<AppConnection, string>> = {
|
||||
[AppConnection.AzureKeyVault]: "azureKeyVaultConnectionFormData",
|
||||
[AppConnection.AzureAppConfiguration]: "azureAppConfigurationConnectionFormData",
|
||||
[AppConnection.AzureClientSecrets]: "azureClientSecretsConnectionFormData",
|
||||
[AppConnection.AzureDevOps]: "azureDevOpsConnectionFormData"
|
||||
[AppConnection.AzureDevOps]: "azureDevOpsConnectionFormData",
|
||||
[AppConnection.Heroku]: "herokuConnectionFormData"
|
||||
};
|
||||
|
||||
export const OAuthCallbackPage = () => {
|
||||
@@ -83,7 +85,7 @@ export const OAuthCallbackPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleGitlab = useCallback(async () => {
|
||||
const handleGitLab = useCallback(async () => {
|
||||
const formData = getFormData(AppConnection.GitLab);
|
||||
if (formData === null) return null;
|
||||
|
||||
@@ -375,7 +377,7 @@ export const OAuthCallbackPage = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleGithub = useCallback(async () => {
|
||||
const handleGitHub = useCallback(async () => {
|
||||
const formData = getFormData(AppConnection.GitHub);
|
||||
if (formData === null) return null;
|
||||
|
||||
@@ -463,7 +465,7 @@ export const OAuthCallbackPage = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleGithubRadar = useCallback(async () => {
|
||||
const handleGitHubRadar = useCallback(async () => {
|
||||
const formData = getFormData(AppConnection.GitHubRadar);
|
||||
if (formData === null) return null;
|
||||
|
||||
@@ -520,6 +522,61 @@ export const OAuthCallbackPage = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleHeroku = useCallback(async () => {
|
||||
const formData = getFormData(AppConnection.Heroku);
|
||||
if (formData === null) return null;
|
||||
|
||||
clearState(AppConnection.Heroku);
|
||||
|
||||
const { connectionId, name, description, returnUrl, projectId } = formData;
|
||||
|
||||
let connection: TAppConnection;
|
||||
|
||||
try {
|
||||
if (connectionId) {
|
||||
connection = await updateAppConnection.mutateAsync({
|
||||
app: AppConnection.Heroku,
|
||||
connectionId,
|
||||
credentials: {
|
||||
code: code as string
|
||||
}
|
||||
});
|
||||
} else {
|
||||
connection = await createAppConnection.mutateAsync({
|
||||
app: AppConnection.Heroku,
|
||||
name,
|
||||
description,
|
||||
method: HerokuConnectionMethod.OAuth,
|
||||
projectId,
|
||||
credentials: {
|
||||
code: code as string
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e: any) {
|
||||
createNotification({
|
||||
title: `Failed to ${connectionId ? "update" : "add"} Heroku Connection`,
|
||||
text: e.message,
|
||||
type: "error"
|
||||
});
|
||||
navigate({
|
||||
to: returnUrl,
|
||||
params: {
|
||||
projectId
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
connectionId,
|
||||
returnUrl,
|
||||
appConnectionName: formData.app,
|
||||
projectId,
|
||||
connection
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Ensure that the localstorage is ready for use, to avoid the form data being malformed
|
||||
useEffect(() => {
|
||||
if (!isReady) {
|
||||
@@ -540,11 +597,11 @@ export const OAuthCallbackPage = () => {
|
||||
} | null = null;
|
||||
|
||||
if (appConnection === AppConnection.GitHub) {
|
||||
data = await handleGithub();
|
||||
data = await handleGitHub();
|
||||
} else if (appConnection === AppConnection.GitHubRadar) {
|
||||
data = await handleGithubRadar();
|
||||
data = await handleGitHubRadar();
|
||||
} else if (appConnection === AppConnection.GitLab) {
|
||||
data = await handleGitlab();
|
||||
data = await handleGitLab();
|
||||
} else if (appConnection === AppConnection.AzureKeyVault) {
|
||||
data = await handleAzureKeyVault();
|
||||
} else if (appConnection === AppConnection.AzureAppConfiguration) {
|
||||
@@ -553,6 +610,8 @@ export const OAuthCallbackPage = () => {
|
||||
data = await handleAzureClientSecrets();
|
||||
} else if (appConnection === AppConnection.AzureDevOps) {
|
||||
data = await handleAzureDevOps();
|
||||
} else if (appConnection === AppConnection.Heroku) {
|
||||
data = await handleHeroku();
|
||||
}
|
||||
|
||||
if (data) {
|
||||
|
||||
@@ -6,7 +6,8 @@ import {
|
||||
TAzureKeyVaultConnection,
|
||||
TGitHubConnection,
|
||||
TGitHubRadarConnection,
|
||||
TGitLabConnection
|
||||
TGitLabConnection,
|
||||
THerokuConnection
|
||||
} from "@app/hooks/api/appConnections";
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
|
||||
@@ -17,10 +18,10 @@ type BaseFormData = {
|
||||
projectId: string;
|
||||
};
|
||||
|
||||
export type GithubFormData = BaseFormData &
|
||||
export type GitHubFormData = BaseFormData &
|
||||
Pick<TGitHubConnection, "name" | "method" | "description" | "gatewayId" | "credentials">;
|
||||
|
||||
export type GithubRadarFormData = BaseFormData &
|
||||
export type GitHubRadarFormData = BaseFormData &
|
||||
Pick<TGitHubRadarConnection, "name" | "method" | "description">;
|
||||
|
||||
export type GitLabFormData = BaseFormData &
|
||||
@@ -51,9 +52,12 @@ export type AzureDevOpsFormData = BaseFormData &
|
||||
Pick<TAzureDevOpsConnection, "name" | "method" | "description"> &
|
||||
(Pick<OAuthCredentials, "tenantId" | "orgName"> | Pick<AccessTokenCredentials, "orgName">);
|
||||
|
||||
export type HerokuFormData = BaseFormData &
|
||||
Pick<THerokuConnection, "name" | "method" | "description">;
|
||||
|
||||
export type FormDataMap = {
|
||||
[AppConnection.GitHub]: GithubFormData & { app: AppConnection.GitHub };
|
||||
[AppConnection.GitHubRadar]: GithubRadarFormData & { app: AppConnection.GitHubRadar };
|
||||
[AppConnection.GitHub]: GitHubFormData & { app: AppConnection.GitHub };
|
||||
[AppConnection.GitHubRadar]: GitHubRadarFormData & { app: AppConnection.GitHubRadar };
|
||||
[AppConnection.GitLab]: GitLabFormData & { app: AppConnection.GitLab };
|
||||
[AppConnection.AzureKeyVault]: AzureKeyVaultFormData & { app: AppConnection.AzureKeyVault };
|
||||
[AppConnection.AzureAppConfiguration]: AzureAppConfigurationFormData & {
|
||||
@@ -65,4 +69,7 @@ export type FormDataMap = {
|
||||
[AppConnection.AzureDevOps]: AzureDevOpsFormData & {
|
||||
app: AppConnection.AzureDevOps;
|
||||
};
|
||||
[AppConnection.Heroku]: HerokuFormData & {
|
||||
app: AppConnection.Heroku;
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user