fix: migrate heroku oauth connection to new oauth connection format

This commit is contained in:
Scott Wilson
2025-09-19 09:51:56 -07:00
parent 3c9ad328a9
commit 2786d49cad
13 changed files with 138 additions and 27 deletions

View File

@@ -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:

View File

@@ -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 =

View File

@@ -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) {

View File

@@ -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
})
);

View File

@@ -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) {

View File

@@ -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;
};
};