feat(secret-sync): Add gitlab secret sync

This commit is contained in:
carlosmonastyrski
2025-06-20 21:13:14 -03:00
parent e5352e7aa8
commit e201d77a8f
99 changed files with 2912 additions and 56 deletions
@@ -3,11 +3,13 @@ import { useNavigate, useSearch } from "@tanstack/react-router";
import { ROUTE_PATHS } from "@app/const/routes";
import { useWorkspace } from "@app/context";
import { useAuthorizeIntegration } from "@app/hooks/api";
import { useCreateAppConnection, useUpdateAppConnection } from "@app/hooks/api/appConnections";
import { GitlabConnectionMethod } from "@app/hooks/api/appConnections/types/gitlab-connection";
export const GitLabOAuthCallbackPage = () => {
const navigate = useNavigate();
const { mutateAsync } = useAuthorizeIntegration();
const { mutateAsync: createAppConnection } = useCreateAppConnection();
const { mutateAsync: updateAppConnection } = useUpdateAppConnection();
const { code, state } = useSearch({
from: ROUTE_PATHS.SecretManager.Integratons.GitlabOauthCallbackPage.id
@@ -17,37 +19,83 @@ export const GitLabOAuthCallbackPage = () => {
useEffect(() => {
(async () => {
try {
// validate state
const [csrfToken, url] = (state as string).split("|", 2);
// Validate CSRF state token
const [csrfToken] = (state as string).split("|", 2);
const storedState = localStorage.getItem("latestCSRFToken");
if (csrfToken !== storedState) {
console.error("CSRF token mismatch");
navigate({
to: "/organization/app-connections",
search: { error: "invalid_state" }
});
return;
}
if (csrfToken !== localStorage.getItem("latestCSRFToken")) return;
localStorage.removeItem("latestCSRFToken");
const integrationAuth = await mutateAsync({
workspaceId: currentWorkspace.id,
code: code as string,
integration: "gitlab",
...(url === ""
? {}
: {
url
})
});
// Retrieve stored form dataAdd commentMore actions
const storedFormData = localStorage.getItem("gitlabConnectionFormData");
if (!storedFormData) {
console.error("No stored form data found");
navigate({
to: "/organization/app-connections",
search: { error: "missing_form_data" }
});
return;
}
const formData = JSON.parse(storedFormData);
localStorage.removeItem("gitlabConnectionFormData");
// Prepare app connection data with OAuth credentials
const connectionData = {
...formData,
method: GitlabConnectionMethod.OAuth,
credentials: {
code: code as string
}
};
let appConnection;
// Create or update app connection
if (formData.isUpdate && formData.connectionId) {
appConnection = await updateAppConnection({
connectionId: formData.connectionId,
...connectionData
});
} else {
appConnection = await createAppConnection({
workspaceId: currentWorkspace.id,
...connectionData
});
}
// Navigate to success page or app connections list
navigate({
to: "/secret-manager/$projectId/integrations/gitlab/create",
params: {
projectId: currentWorkspace.id
},
to: "/organization/app-connections",
search: {
integrationAuthId: integrationAuth.id
success: formData.isUpdate ? "connection_updated" : "connection_created",
connectionId: appConnection.id
}
});
} catch (err) {
console.error(err);
console.error("Error handling GitLab OAuth callback:", err);
navigate({
to: "/organization/app-connections",
search: { error: "connection_failed" }
});
}
})();
}, []);
}, [code, state, navigate, createAppConnection, updateAppConnection, currentWorkspace.id]);
return <div />;
return (
<div className="flex h-screen items-center justify-center">
<div className="text-center">
<div className="mx-auto mb-4 h-8 w-8 animate-spin rounded-full border-b-2 border-primary" />
<p className="text-gray-600">Connecting to GitLab...</p>
</div>
</div>
);
};