mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 17:27:40 +00:00
feat(secret-sync): Gitlab PR suggestions
This commit is contained in:
@@ -4,7 +4,9 @@ import { AxiosError, AxiosResponse } from "axios";
|
|||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { request } from "@app/lib/config/request";
|
import { request } from "@app/lib/config/request";
|
||||||
import { BadRequestError, InternalServerError } from "@app/lib/errors";
|
import { BadRequestError, InternalServerError } from "@app/lib/errors";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
|
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";
|
||||||
import { encryptAppConnectionCredentials } from "@app/services/app-connection/app-connection-fns";
|
import { encryptAppConnectionCredentials } from "@app/services/app-connection/app-connection-fns";
|
||||||
import { IntegrationUrls } from "@app/services/integration-auth/integration-list";
|
import { IntegrationUrls } from "@app/services/integration-auth/integration-list";
|
||||||
@@ -37,6 +39,14 @@ export const getGitLabConnectionListItem = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getGitLabInstanceUrl = async (instanceUrl?: string) => {
|
||||||
|
const gitLabInstanceUrl = instanceUrl ? removeTrailingSlash(instanceUrl) : IntegrationUrls.GITLAB_URL;
|
||||||
|
|
||||||
|
await blockLocalAndPrivateIpAddresses(gitLabInstanceUrl);
|
||||||
|
|
||||||
|
return gitLabInstanceUrl;
|
||||||
|
};
|
||||||
|
|
||||||
export const refreshGitLabToken = async (
|
export const refreshGitLabToken = async (
|
||||||
refreshToken: string,
|
refreshToken: string,
|
||||||
appId: string,
|
appId: string,
|
||||||
@@ -61,16 +71,13 @@ export const refreshGitLabToken = async (
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data } = await request.post<GitLabOAuthTokenResponse>(
|
const url = await getGitLabInstanceUrl(instanceUrl);
|
||||||
`${instanceUrl ? `${instanceUrl}/oauth/token` : IntegrationUrls.GITLAB_TOKEN_URL}`,
|
const { data } = await request.post<GitLabOAuthTokenResponse>(`${url}/oauth/token`, payload.toString(), {
|
||||||
payload.toString(),
|
|
||||||
{
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
Accept: "application/json"
|
Accept: "application/json"
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const expiresAt = new Date(Date.now() + data.expires_in * 1000 - 60000);
|
const expiresAt = new Date(Date.now() + data.expires_in * 1000 - 60000);
|
||||||
|
|
||||||
@@ -118,17 +125,14 @@ export const exchangeGitLabOAuthCode = async (
|
|||||||
client_secret: CLIENT_SECRET_GITLAB_LOGIN,
|
client_secret: CLIENT_SECRET_GITLAB_LOGIN,
|
||||||
redirect_uri: `${SITE_URL}/integrations/gitlab/oauth2/callback`
|
redirect_uri: `${SITE_URL}/integrations/gitlab/oauth2/callback`
|
||||||
});
|
});
|
||||||
|
const url = await getGitLabInstanceUrl(instanceUrl);
|
||||||
|
|
||||||
const response = await request.post<GitLabOAuthTokenResponse>(
|
const response = await request.post<GitLabOAuthTokenResponse>(`${url}/oauth/token`, payload.toString(), {
|
||||||
instanceUrl ? `${instanceUrl}/oauth/token` : IntegrationUrls.GITLAB_TOKEN_URL,
|
|
||||||
payload.toString(),
|
|
||||||
{
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
Accept: "application/json"
|
Accept: "application/json"
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
if (!response.data) {
|
if (!response.data) {
|
||||||
throw new InternalServerError({
|
throw new InternalServerError({
|
||||||
@@ -169,15 +173,13 @@ export const validateGitLabConnectionCredentials = async (config: TGitLabConnect
|
|||||||
let response: AxiosResponse<TGitLabProject[]> | null = null;
|
let response: AxiosResponse<TGitLabProject[]> | null = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
response = await request.get<TGitLabProject[]>(
|
const url = await getGitLabInstanceUrl(inputCredentials.instanceUrl);
|
||||||
`${inputCredentials.instanceUrl ? `${inputCredentials.instanceUrl}/api` : IntegrationUrls.GITLAB_API_URL}/v4/groups`,
|
response = await request.get<TGitLabProject[]>(`${url}/api/v4/groups`, {
|
||||||
{
|
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${accessToken}`,
|
Authorization: `Bearer ${accessToken}`,
|
||||||
Accept: "application/json"
|
Accept: "application/json"
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof AxiosError) {
|
if (error instanceof AxiosError) {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
@@ -236,9 +238,8 @@ export const listGitLabProjects = async ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gitLabApiUrl = appConnection.credentials.instanceUrl
|
const url = await getGitLabInstanceUrl(appConnection.credentials.instanceUrl);
|
||||||
? `${appConnection.credentials.instanceUrl}/api/v4`
|
const gitLabApiUrl = `${url}/api/v4`;
|
||||||
: `${IntegrationUrls.GITLAB_API_URL}/v4`;
|
|
||||||
|
|
||||||
const projects: TGitLabProject[] = [];
|
const projects: TGitLabProject[] = [];
|
||||||
let page = 1;
|
let page = 1;
|
||||||
@@ -433,9 +434,8 @@ export const listGitLabGroups = async ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gitLabApiUrl = appConnection.credentials.instanceUrl
|
const url = await getGitLabInstanceUrl(appConnection.credentials.instanceUrl);
|
||||||
? `${appConnection.credentials.instanceUrl}/api/v4`
|
const gitLabApiUrl = `${url}/api/v4`;
|
||||||
: `${IntegrationUrls.GITLAB_API_URL}/v4`;
|
|
||||||
|
|
||||||
const groups: TGitLabGroup[] = [];
|
const groups: TGitLabGroup[] = [];
|
||||||
let page = 1;
|
let page = 1;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
import { request } from "@app/lib/config/request";
|
import { request } from "@app/lib/config/request";
|
||||||
|
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
||||||
import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
|
import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
|
||||||
import { GitLabConnectionMethod, refreshGitLabToken, TGitLabConnection } from "@app/services/app-connection/gitlab";
|
import { GitLabConnectionMethod, refreshGitLabToken, TGitLabConnection } from "@app/services/app-connection/gitlab";
|
||||||
import { IntegrationUrls } from "@app/services/integration-auth/integration-list";
|
import { IntegrationUrls } from "@app/services/integration-auth/integration-list";
|
||||||
@@ -55,8 +56,9 @@ const getValidAccessToken = async (
|
|||||||
return connection.credentials.accessToken;
|
return connection.credentials.accessToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGitLabApiUrl = (connection: TGitLabConnection): string => {
|
const getGitLabApiUrl = async (connection: TGitLabConnection): Promise<string> => {
|
||||||
const baseUrl = connection.credentials.instanceUrl || IntegrationUrls.GITLAB_API_URL;
|
const baseUrl = connection.credentials.instanceUrl || IntegrationUrls.GITLAB_API_URL;
|
||||||
|
await blockLocalAndPrivateIpAddresses(baseUrl);
|
||||||
return baseUrl.includes("/api") ? baseUrl : `${baseUrl}/api`;
|
return baseUrl.includes("/api") ? baseUrl : `${baseUrl}/api`;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -76,7 +78,7 @@ const getGitLabVariables = async ({
|
|||||||
targetEnvironment?: string;
|
targetEnvironment?: string;
|
||||||
}): Promise<TGitLabVariable[]> => {
|
}): Promise<TGitLabVariable[]> => {
|
||||||
try {
|
try {
|
||||||
const apiUrl = getGitLabApiUrl(connection);
|
const apiUrl = await getGitLabApiUrl(connection);
|
||||||
const baseEndpoint = buildVariablesEndpoint(apiUrl, projectId);
|
const baseEndpoint = buildVariablesEndpoint(apiUrl, projectId);
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
@@ -131,7 +133,7 @@ const createGitLabVariable = async ({
|
|||||||
variable: TGitLabVariableCreate;
|
variable: TGitLabVariableCreate;
|
||||||
}): Promise<void> => {
|
}): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const apiUrl = getGitLabApiUrl(connection);
|
const apiUrl = await getGitLabApiUrl(connection);
|
||||||
const endpoint = buildVariablesEndpoint(apiUrl, projectId);
|
const endpoint = buildVariablesEndpoint(apiUrl, projectId);
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
@@ -177,7 +179,7 @@ const updateGitLabVariable = async ({
|
|||||||
targetEnvironment?: string;
|
targetEnvironment?: string;
|
||||||
}): Promise<void> => {
|
}): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const apiUrl = getGitLabApiUrl(connection);
|
const apiUrl = await getGitLabApiUrl(connection);
|
||||||
const baseEndpoint = buildVariablesEndpoint(apiUrl, projectId);
|
const baseEndpoint = buildVariablesEndpoint(apiUrl, projectId);
|
||||||
let url = `${baseEndpoint}/${encodeURIComponent(key)}`;
|
let url = `${baseEndpoint}/${encodeURIComponent(key)}`;
|
||||||
|
|
||||||
@@ -224,7 +226,7 @@ const deleteGitLabVariable = async ({
|
|||||||
targetEnvironment?: string;
|
targetEnvironment?: string;
|
||||||
}): Promise<void> => {
|
}): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const apiUrl = getGitLabApiUrl(connection);
|
const apiUrl = await getGitLabApiUrl(connection);
|
||||||
const baseEndpoint = buildVariablesEndpoint(apiUrl, projectId);
|
const baseEndpoint = buildVariablesEndpoint(apiUrl, projectId);
|
||||||
let url = `${baseEndpoint}/${encodeURIComponent(key)}`;
|
let url = `${baseEndpoint}/${encodeURIComponent(key)}`;
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -65,7 +65,7 @@ const SecretProtectionOption = ({
|
|||||||
|
|
||||||
export const GitLabSyncFields = () => {
|
export const GitLabSyncFields = () => {
|
||||||
const { control, setValue } = useFormContext<
|
const { control, setValue } = useFormContext<
|
||||||
TSecretSyncForm & { destination: SecretSync.Gitlab }
|
TSecretSyncForm & { destination: SecretSync.GitLab }
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const connectionId = useWatch({ name: "connection.id", control });
|
const connectionId = useWatch({ name: "connection.id", control });
|
||||||
@@ -259,10 +259,10 @@ export const GitLabSyncFields = () => {
|
|||||||
control={control}
|
control={control}
|
||||||
name="destinationConfig.shouldHideSecrets"
|
name="destinationConfig.shouldHideSecrets"
|
||||||
render={({ field: { onChange, value } }) => (
|
render={({ field: { onChange, value } }) => (
|
||||||
<div className='"max-h-32 opacity-100" transition-all duration-300'>
|
<div className="max-h-32 opacity-100 transition-all duration-300">
|
||||||
<SecretProtectionOption
|
<SecretProtectionOption
|
||||||
id="should-hide-secrets"
|
id="should-hide-secrets"
|
||||||
title="Mark Infisical secrets in GitLab as 'Protected' secrets"
|
title="Mark Infisical secrets in GitLab as 'Hidden' secrets"
|
||||||
tooltip="Secrets can only be marked as hidden if they are also masked."
|
tooltip="Secrets can only be marked as hidden if they are also masked."
|
||||||
isEnabled={value || false}
|
isEnabled={value || false}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
|||||||
+1
-1
@@ -71,7 +71,7 @@ export const SecretSyncDestinationFields = () => {
|
|||||||
return <RenderSyncFields />;
|
return <RenderSyncFields />;
|
||||||
case SecretSync.Flyio:
|
case SecretSync.Flyio:
|
||||||
return <FlyioSyncFields />;
|
return <FlyioSyncFields />;
|
||||||
case SecretSync.Gitlab:
|
case SecretSync.GitLab:
|
||||||
return <GitLabSyncFields />;
|
return <GitLabSyncFields />;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unhandled Destination Config Field: ${destination}`);
|
throw new Error(`Unhandled Destination Config Field: ${destination}`);
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => {
|
|||||||
case SecretSync.Heroku:
|
case SecretSync.Heroku:
|
||||||
case SecretSync.Render:
|
case SecretSync.Render:
|
||||||
case SecretSync.Flyio:
|
case SecretSync.Flyio:
|
||||||
case SecretSync.Gitlab:
|
case SecretSync.GitLab:
|
||||||
AdditionalSyncOptionsFieldsComponent = null;
|
AdditionalSyncOptionsFieldsComponent = null;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import { TSecretSyncForm } from "@app/components/secret-syncs/forms/schemas";
|
|||||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||||
|
|
||||||
export const GitLabSyncReviewFields = () => {
|
export const GitLabSyncReviewFields = () => {
|
||||||
const { watch } = useFormContext<TSecretSyncForm & { destination: SecretSync.Gitlab }>();
|
const { watch } = useFormContext<TSecretSyncForm & { destination: SecretSync.GitLab }>();
|
||||||
const projectId = watch("destinationConfig.projectId");
|
const projectId = watch("destinationConfig.projectId");
|
||||||
const targetEnvironment = watch("destinationConfig.targetEnvironment");
|
const targetEnvironment = watch("destinationConfig.targetEnvironment");
|
||||||
const groupId = watch("destinationConfig.groupId");
|
const groupId = watch("destinationConfig.groupId");
|
||||||
|
|||||||
+1
-1
@@ -117,7 +117,7 @@ export const SecretSyncReviewFields = () => {
|
|||||||
case SecretSync.Flyio:
|
case SecretSync.Flyio:
|
||||||
DestinationFieldsComponent = <FlyioSyncReviewFields />;
|
DestinationFieldsComponent = <FlyioSyncReviewFields />;
|
||||||
break;
|
break;
|
||||||
case SecretSync.Gitlab:
|
case SecretSync.GitLab:
|
||||||
DestinationFieldsComponent = <GitLabSyncReviewFields />;
|
DestinationFieldsComponent = <GitLabSyncReviewFields />;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { GitlabSyncScope } from "@app/hooks/api/secretSyncs/types/gitlab-sync";
|
|||||||
|
|
||||||
export const GitlabSyncDestinationSchema = BaseSecretSyncSchema().merge(
|
export const GitlabSyncDestinationSchema = BaseSecretSyncSchema().merge(
|
||||||
z.object({
|
z.object({
|
||||||
destination: z.literal(SecretSync.Gitlab),
|
destination: z.literal(SecretSync.GitLab),
|
||||||
destinationConfig: z.discriminatedUnion("scope", [
|
destinationConfig: z.discriminatedUnion("scope", [
|
||||||
z.object({
|
z.object({
|
||||||
scope: z.literal(GitlabSyncScope.Individual),
|
scope: z.literal(GitlabSyncScope.Individual),
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export const APP_CONNECTION_MAP: Record<
|
|||||||
[AppConnection.Heroku]: { name: "Heroku", image: "Heroku.png" },
|
[AppConnection.Heroku]: { name: "Heroku", image: "Heroku.png" },
|
||||||
[AppConnection.Render]: { name: "Render", image: "Render.png" },
|
[AppConnection.Render]: { name: "Render", image: "Render.png" },
|
||||||
[AppConnection.Flyio]: { name: "Fly.io", image: "Flyio.svg" },
|
[AppConnection.Flyio]: { name: "Fly.io", image: "Flyio.svg" },
|
||||||
[AppConnection.Gitlab]: { name: "Gitlab", image: "GitLab.png" }
|
[AppConnection.Gitlab]: { name: "GitLab", image: "GitLab.png" }
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) => {
|
export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) => {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export const SECRET_SYNC_MAP: Record<SecretSync, { name: string; image: string }
|
|||||||
name: "Fly.io",
|
name: "Fly.io",
|
||||||
image: "Flyio.svg"
|
image: "Flyio.svg"
|
||||||
},
|
},
|
||||||
[SecretSync.Gitlab]: {
|
[SecretSync.GitLab]: {
|
||||||
name: "Gitlab",
|
name: "Gitlab",
|
||||||
image: "GitLab.png"
|
image: "GitLab.png"
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ export const SECRET_SYNC_CONNECTION_MAP: Record<SecretSync, AppConnection> = {
|
|||||||
[SecretSync.Heroku]: AppConnection.Heroku,
|
[SecretSync.Heroku]: AppConnection.Heroku,
|
||||||
[SecretSync.Render]: AppConnection.Render,
|
[SecretSync.Render]: AppConnection.Render,
|
||||||
[SecretSync.Flyio]: AppConnection.Flyio,
|
[SecretSync.Flyio]: AppConnection.Flyio,
|
||||||
[SecretSync.Gitlab]: AppConnection.Gitlab
|
[SecretSync.GitLab]: AppConnection.Gitlab
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP: Record<
|
export const SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP: Record<
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export enum SecretSync {
|
|||||||
Heroku = "heroku",
|
Heroku = "heroku",
|
||||||
Render = "render",
|
Render = "render",
|
||||||
Flyio = "flyio",
|
Flyio = "flyio",
|
||||||
Gitlab = "gitlab"
|
GitLab = "gitlab"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SecretSyncStatus {
|
export enum SecretSyncStatus {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export enum GitlabSyncScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type TGitlabSync = TRootSecretSync & {
|
export type TGitlabSync = TRootSecretSync & {
|
||||||
destination: SecretSync.Gitlab;
|
destination: SecretSync.GitLab;
|
||||||
destinationConfig:
|
destinationConfig:
|
||||||
| {
|
| {
|
||||||
scope: GitlabSyncScope.Individual;
|
scope: GitlabSyncScope.Individual;
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ export const SecretSyncDestinationCol = ({ secretSync }: Props) => {
|
|||||||
return <RenderSyncDestinationCol secretSync={secretSync} />;
|
return <RenderSyncDestinationCol secretSync={secretSync} />;
|
||||||
case SecretSync.Flyio:
|
case SecretSync.Flyio:
|
||||||
return <FlyioSyncDestinationCol secretSync={secretSync} />;
|
return <FlyioSyncDestinationCol secretSync={secretSync} />;
|
||||||
case SecretSync.Gitlab:
|
case SecretSync.GitLab:
|
||||||
return <GitLabSyncDestinationCol secretSync={secretSync} />;
|
return <GitLabSyncDestinationCol secretSync={secretSync} />;
|
||||||
default:
|
default:
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
+1
-1
@@ -128,7 +128,7 @@ export const getSecretSyncDestinationColValues = (secretSync: TSecretSync) => {
|
|||||||
primaryText = destinationConfig.appId;
|
primaryText = destinationConfig.appId;
|
||||||
secondaryText = "App ID";
|
secondaryText = "App ID";
|
||||||
break;
|
break;
|
||||||
case SecretSync.Gitlab:
|
case SecretSync.GitLab:
|
||||||
primaryText = destinationConfig.projectName;
|
primaryText = destinationConfig.projectName;
|
||||||
secondaryText = destinationConfig.projectId;
|
secondaryText = destinationConfig.projectId;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+1
-1
@@ -107,7 +107,7 @@ export const SecretSyncDestinationSection = ({ secretSync, onEditDestination }:
|
|||||||
case SecretSync.Flyio:
|
case SecretSync.Flyio:
|
||||||
DestinationComponents = <FlyioSyncDestinationSection secretSync={secretSync} />;
|
DestinationComponents = <FlyioSyncDestinationSection secretSync={secretSync} />;
|
||||||
break;
|
break;
|
||||||
case SecretSync.Gitlab:
|
case SecretSync.GitLab:
|
||||||
DestinationComponents = <GitLabSyncDestinationSection secretSync={secretSync} />;
|
DestinationComponents = <GitLabSyncDestinationSection secretSync={secretSync} />;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+1
-1
@@ -58,7 +58,7 @@ export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) =
|
|||||||
case SecretSync.Heroku:
|
case SecretSync.Heroku:
|
||||||
case SecretSync.Render:
|
case SecretSync.Render:
|
||||||
case SecretSync.Flyio:
|
case SecretSync.Flyio:
|
||||||
case SecretSync.Gitlab:
|
case SecretSync.GitLab:
|
||||||
AdditionalSyncOptionsComponent = null;
|
AdditionalSyncOptionsComponent = null;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
-1
@@ -33,7 +33,6 @@ export const GitLabOAuthCallbackPage = () => {
|
|||||||
|
|
||||||
localStorage.removeItem("latestCSRFToken");
|
localStorage.removeItem("latestCSRFToken");
|
||||||
|
|
||||||
// Retrieve stored form dataAdd commentMore actions
|
|
||||||
const storedFormData = localStorage.getItem("gitlabConnectionFormData");
|
const storedFormData = localStorage.getItem("gitlabConnectionFormData");
|
||||||
if (!storedFormData) {
|
if (!storedFormData) {
|
||||||
console.error("No stored form data found");
|
console.error("No stored form data found");
|
||||||
|
|||||||
Reference in New Issue
Block a user