mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
refactor: streamline async logic and notification handling across various settings and integration components
This commit is contained in:
@@ -39,40 +39,33 @@ export const AuditLogsRetentionSection = () => {
|
|||||||
if (!currentProject) return null;
|
if (!currentProject) return null;
|
||||||
|
|
||||||
const handleAuditLogsRetentionSubmit = async ({ auditLogsRetentionDays }: TForm) => {
|
const handleAuditLogsRetentionSubmit = async ({ auditLogsRetentionDays }: TForm) => {
|
||||||
try {
|
if (!subscription?.auditLogs) {
|
||||||
if (!subscription?.auditLogs) {
|
handlePopUpOpen("upgradePlan", {
|
||||||
handlePopUpOpen("upgradePlan", {
|
description:
|
||||||
description:
|
"You can only configure audit logs retention if you switch to Infisical's Pro plan."
|
||||||
"You can only configure audit logs retention if you switch to Infisical's Pro plan."
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subscription && auditLogsRetentionDays > subscription?.auditLogsRetentionDays) {
|
|
||||||
handlePopUpOpen("upgradePlan", {
|
|
||||||
description:
|
|
||||||
"To update your audit logs retention period to a higher value, switch to Infisical's Pro plan."
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await updateAuditLogsRetention({
|
|
||||||
auditLogsRetentionDays,
|
|
||||||
projectSlug: currentProject.slug
|
|
||||||
});
|
});
|
||||||
|
|
||||||
createNotification({
|
return;
|
||||||
text: "Successfully updated audit logs retention period",
|
|
||||||
type: "success"
|
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
createNotification({
|
|
||||||
text: "Failed updating audit logs retention period",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subscription && auditLogsRetentionDays > subscription?.auditLogsRetentionDays) {
|
||||||
|
handlePopUpOpen("upgradePlan", {
|
||||||
|
description:
|
||||||
|
"To update your audit logs retention period to a higher value, switch to Infisical's Pro plan."
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await updateAuditLogsRetention({
|
||||||
|
auditLogsRetentionDays,
|
||||||
|
projectSlug: currentProject.slug
|
||||||
|
});
|
||||||
|
|
||||||
|
createNotification({
|
||||||
|
text: "Successfully updated audit logs retention period",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// render only for dedicated/self-hosted instances of Infisical
|
// render only for dedicated/self-hosted instances of Infisical
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { faHome } from "@fortawesome/free-solid-svg-icons";
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
import { OrgPermissionCan } from "@app/components/permissions";
|
||||||
import { RequestProjectAccessModal } from "@app/components/projects";
|
import { RequestProjectAccessModal } from "@app/components/projects";
|
||||||
import { AccessRestrictedBanner, Button } from "@app/components/v2";
|
import { AccessRestrictedBanner, Button } from "@app/components/v2";
|
||||||
@@ -35,19 +34,12 @@ export const ProjectAccessError = () => {
|
|||||||
|
|
||||||
const handleAccessProject = async () => {
|
const handleAccessProject = async () => {
|
||||||
if (!project) return;
|
if (!project) return;
|
||||||
try {
|
await orgAdminAccessProject.mutateAsync({
|
||||||
await orgAdminAccessProject.mutateAsync({
|
projectId: project.id
|
||||||
projectId: project.id
|
});
|
||||||
});
|
await navigate({
|
||||||
await navigate({
|
to: "."
|
||||||
to: "."
|
});
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to access project",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -131,52 +131,44 @@ export const ShareSecretForm = ({
|
|||||||
emails,
|
emails,
|
||||||
shouldLimitView
|
shouldLimitView
|
||||||
}: FormData) => {
|
}: FormData) => {
|
||||||
try {
|
const expiresAt = new Date(new Date().getTime() + Number(expiresIn));
|
||||||
const expiresAt = new Date(new Date().getTime() + Number(expiresIn));
|
|
||||||
|
|
||||||
const processedEmails = emails ? emails.split(",").map((e) => e.trim()) : undefined;
|
const processedEmails = emails ? emails.split(",").map((e) => e.trim()) : undefined;
|
||||||
|
|
||||||
const { id } = await createSharedSecret.mutateAsync({
|
const { id } = await createSharedSecret.mutateAsync({
|
||||||
name,
|
name,
|
||||||
password,
|
password,
|
||||||
secretValue: secret,
|
secretValue: secret,
|
||||||
expiresAt,
|
expiresAt,
|
||||||
expiresAfterViews: shouldLimitView ? Number(viewLimit) : undefined,
|
expiresAfterViews: shouldLimitView ? Number(viewLimit) : undefined,
|
||||||
accessType,
|
accessType,
|
||||||
emails: processedEmails
|
emails: processedEmails
|
||||||
|
});
|
||||||
|
|
||||||
|
if (processedEmails && processedEmails.length > 0) {
|
||||||
|
setSecretLink("");
|
||||||
|
createNotification({
|
||||||
|
text: `Shared secret link emailed to ${processedEmails.length} user(s).`,
|
||||||
|
type: "success"
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
if (processedEmails && processedEmails.length > 0) {
|
const link = new URL(`${window.location.origin}/shared/secret/${id}`);
|
||||||
setSecretLink("");
|
if (subOrganization) {
|
||||||
createNotification({
|
link.searchParams.set("subOrganization", subOrganization);
|
||||||
text: `Shared secret link emailed to ${processedEmails.length} user(s).`,
|
|
||||||
type: "success"
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const link = new URL(`${window.location.origin}/shared/secret/${id}`);
|
|
||||||
if (subOrganization) {
|
|
||||||
link.searchParams.set("subOrganization", subOrganization);
|
|
||||||
}
|
|
||||||
|
|
||||||
setSecretLink(link.toString());
|
|
||||||
|
|
||||||
navigator.clipboard.writeText(link.toString());
|
|
||||||
setCopyTextSecret("secret");
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
text: "Shared secret link copied to clipboard.",
|
|
||||||
type: "success"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reset();
|
setSecretLink(link.toString());
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
navigator.clipboard.writeText(link.toString());
|
||||||
|
setCopyTextSecret("secret");
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Failed to create a shared secret.",
|
text: "Shared secret link copied to clipboard.",
|
||||||
type: "error"
|
type: "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (secretLink === null)
|
if (secretLink === null)
|
||||||
|
|||||||
@@ -140,22 +140,15 @@ export const RollbackPreviewTab = (): JSX.Element => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleRollback = async (): Promise<void> => {
|
const handleRollback = async (): Promise<void> => {
|
||||||
try {
|
await rollback(message);
|
||||||
await rollback(message);
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
type: "success",
|
type: "success",
|
||||||
text: "Rollback completed successfully"
|
text: "Rollback completed successfully"
|
||||||
});
|
});
|
||||||
|
|
||||||
handlePopUpClose("rollbackConfirm");
|
handlePopUpClose("rollbackConfirm");
|
||||||
goBackToHistory();
|
goBackToHistory();
|
||||||
} catch (error) {
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: error instanceof Error ? error.message : "Failed to rollback changes"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const folderChanges: FolderChanges[] = rollbackChangesNested || [];
|
const folderChanges: FolderChanges[] = rollbackChangesNested || [];
|
||||||
|
|||||||
@@ -53,28 +53,20 @@ export const IntegrationDetailsByIDPage = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const handleIntegrationDelete = async (shouldDeleteIntegrationSecrets: boolean) => {
|
const handleIntegrationDelete = async (shouldDeleteIntegrationSecrets: boolean) => {
|
||||||
try {
|
await deleteIntegration({
|
||||||
await deleteIntegration({
|
id: integrationId,
|
||||||
id: integrationId,
|
workspaceId: currentProject.id,
|
||||||
workspaceId: currentProject.id,
|
shouldDeleteIntegrationSecrets
|
||||||
shouldDeleteIntegrationSecrets
|
});
|
||||||
});
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
type: "success",
|
type: "success",
|
||||||
text: "Deleted integration"
|
text: "Deleted integration"
|
||||||
});
|
});
|
||||||
|
|
||||||
await navigate({
|
await navigate({
|
||||||
to: `/${ProjectType.SecretManager}/${projectId}/integrations`
|
to: `/${ProjectType.SecretManager}/${projectId}/integrations`
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Failed to delete integration"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||||
|
|||||||
@@ -488,55 +488,47 @@ export const OverviewPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSecretCreate = async (env: string, key: string, value: string) => {
|
const handleSecretCreate = async (env: string, key: string, value: string) => {
|
||||||
try {
|
// create folder if not existing
|
||||||
// create folder if not existing
|
if (secretPath !== "/") {
|
||||||
if (secretPath !== "/") {
|
// /hello/world -> [hello","world"]
|
||||||
// /hello/world -> [hello","world"]
|
const pathSegment = secretPath.split("/").filter(Boolean);
|
||||||
const pathSegment = secretPath.split("/").filter(Boolean);
|
const parentPath = `/${pathSegment.slice(0, -1).join("/")}`;
|
||||||
const parentPath = `/${pathSegment.slice(0, -1).join("/")}`;
|
const folderName = pathSegment.at(-1);
|
||||||
const folderName = pathSegment.at(-1);
|
const canCreateFolder = permission.can(
|
||||||
const canCreateFolder = permission.can(
|
ProjectPermissionActions.Create,
|
||||||
ProjectPermissionActions.Create,
|
subject(ProjectPermissionSub.SecretFolders, {
|
||||||
subject(ProjectPermissionSub.SecretFolders, {
|
environment: env,
|
||||||
environment: env,
|
secretPath: parentPath
|
||||||
secretPath: parentPath
|
})
|
||||||
})
|
);
|
||||||
);
|
if (folderName && parentPath && canCreateFolder) {
|
||||||
if (folderName && parentPath && canCreateFolder) {
|
await getOrCreateFolder({
|
||||||
await getOrCreateFolder({
|
projectId,
|
||||||
projectId,
|
path: parentPath,
|
||||||
path: parentPath,
|
environment: env,
|
||||||
environment: env,
|
name: folderName
|
||||||
name: folderName
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const result = await createSecretV3({
|
}
|
||||||
environment: env,
|
const result = await createSecretV3({
|
||||||
projectId,
|
environment: env,
|
||||||
secretPath,
|
projectId,
|
||||||
secretKey: key,
|
secretPath,
|
||||||
secretValue: value,
|
secretKey: key,
|
||||||
secretComment: "",
|
secretValue: value,
|
||||||
type: SecretType.Shared
|
secretComment: "",
|
||||||
});
|
type: SecretType.Shared
|
||||||
|
});
|
||||||
|
|
||||||
if ("approval" in result) {
|
if ("approval" in result) {
|
||||||
createNotification({
|
|
||||||
type: "info",
|
|
||||||
text: "Requested change has been sent for review"
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
createNotification({
|
|
||||||
type: "success",
|
|
||||||
text: "Successfully created secret"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
createNotification({
|
createNotification({
|
||||||
type: "error",
|
type: "info",
|
||||||
text: "Failed to create secret"
|
text: "Requested change has been sent for review"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
createNotification({
|
||||||
|
type: "success",
|
||||||
|
text: "Successfully created secret"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -565,63 +557,47 @@ export const OverviewPage = () => {
|
|||||||
secretValue = undefined;
|
secretValue = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
const result = await updateSecretV3({
|
||||||
const result = await updateSecretV3({
|
environment: env,
|
||||||
environment: env,
|
projectId,
|
||||||
projectId,
|
secretPath,
|
||||||
secretPath,
|
secretKey: key,
|
||||||
secretKey: key,
|
secretValue,
|
||||||
secretValue,
|
type
|
||||||
type
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if ("approval" in result) {
|
if ("approval" in result) {
|
||||||
createNotification({
|
|
||||||
type: "info",
|
|
||||||
text: "Requested change has been sent for review"
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
createNotification({
|
|
||||||
type: "success",
|
|
||||||
text: "Successfully updated secret"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
createNotification({
|
createNotification({
|
||||||
type: "error",
|
type: "info",
|
||||||
text: "Failed to update secret"
|
text: "Requested change has been sent for review"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
createNotification({
|
||||||
|
type: "success",
|
||||||
|
text: "Successfully updated secret"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSecretDelete = async (env: string, key: string, secretId?: string) => {
|
const handleSecretDelete = async (env: string, key: string, secretId?: string) => {
|
||||||
try {
|
const result = await deleteSecretV3({
|
||||||
const result = await deleteSecretV3({
|
environment: env,
|
||||||
environment: env,
|
projectId,
|
||||||
projectId,
|
secretPath,
|
||||||
secretPath,
|
secretKey: key,
|
||||||
secretKey: key,
|
secretId,
|
||||||
secretId,
|
type: SecretType.Shared
|
||||||
type: SecretType.Shared
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if ("approval" in result) {
|
if ("approval" in result) {
|
||||||
createNotification({
|
|
||||||
type: "info",
|
|
||||||
text: "Requested change has been sent for review"
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
createNotification({
|
|
||||||
type: "success",
|
|
||||||
text: "Successfully deleted secret"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
createNotification({
|
createNotification({
|
||||||
type: "error",
|
type: "info",
|
||||||
text: "Failed to delete secret"
|
text: "Requested change has been sent for review"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
createNotification({
|
||||||
|
type: "success",
|
||||||
|
text: "Successfully deleted secret"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -193,19 +193,12 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
|
|||||||
const slugSchema = z.string().trim().toLowerCase().min(1);
|
const slugSchema = z.string().trim().toLowerCase().min(1);
|
||||||
const createNewTag = async (slug: string) => {
|
const createNewTag = async (slug: string) => {
|
||||||
// TODO: Replace with slugSchema generic
|
// TODO: Replace with slugSchema generic
|
||||||
try {
|
const parsedSlug = slugSchema.parse(slug);
|
||||||
const parsedSlug = slugSchema.parse(slug);
|
await createWsTag.mutateAsync({
|
||||||
await createWsTag.mutateAsync({
|
projectId,
|
||||||
projectId,
|
tagSlug: parsedSlug,
|
||||||
tagSlug: parsedSlug,
|
tagColor: ""
|
||||||
tagColor: ""
|
});
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Failed to create new tag"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -77,70 +77,55 @@ export const CreateSecretForm = ({
|
|||||||
const slugSchema = z.string().trim().toLowerCase().min(1);
|
const slugSchema = z.string().trim().toLowerCase().min(1);
|
||||||
const createNewTag = async (slug: string) => {
|
const createNewTag = async (slug: string) => {
|
||||||
// TODO: Replace with slugSchema generic
|
// TODO: Replace with slugSchema generic
|
||||||
try {
|
const parsedSlug = slugSchema.parse(slug);
|
||||||
const parsedSlug = slugSchema.parse(slug);
|
await createWsTag.mutateAsync({
|
||||||
await createWsTag.mutateAsync({
|
projectId,
|
||||||
projectId,
|
tagSlug: parsedSlug,
|
||||||
tagSlug: parsedSlug,
|
tagColor: ""
|
||||||
tagColor: ""
|
});
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Failed to create new tag"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFormSubmit = async ({ key, value, tags }: TFormSchema) => {
|
const handleFormSubmit = async ({ key, value, tags }: TFormSchema) => {
|
||||||
try {
|
if (isBatchMode) {
|
||||||
if (isBatchMode) {
|
const pendingSecretCreate: PendingSecretCreate = {
|
||||||
const pendingSecretCreate: PendingSecretCreate = {
|
id: key,
|
||||||
id: key,
|
type: PendingAction.Create,
|
||||||
type: PendingAction.Create,
|
|
||||||
secretKey: key,
|
|
||||||
secretValue: value || "",
|
|
||||||
secretComment: "",
|
|
||||||
tags: tags?.map((el) => ({ id: el.value, slug: el.label })),
|
|
||||||
timestamp: Date.now(),
|
|
||||||
resourceType: "secret"
|
|
||||||
};
|
|
||||||
addPendingChange(pendingSecretCreate, {
|
|
||||||
projectId,
|
|
||||||
|
|
||||||
environment,
|
|
||||||
secretPath
|
|
||||||
});
|
|
||||||
closePopUp(PopUpNames.CreateSecretForm);
|
|
||||||
reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await createSecretV3({
|
|
||||||
environment,
|
|
||||||
projectId,
|
|
||||||
secretPath,
|
|
||||||
secretKey: key,
|
secretKey: key,
|
||||||
secretValue: value || "",
|
secretValue: value || "",
|
||||||
secretComment: "",
|
secretComment: "",
|
||||||
type: SecretType.Shared,
|
tags: tags?.map((el) => ({ id: el.value, slug: el.label })),
|
||||||
tagIds: tags?.map((el) => el.value)
|
timestamp: Date.now(),
|
||||||
|
resourceType: "secret"
|
||||||
|
};
|
||||||
|
addPendingChange(pendingSecretCreate, {
|
||||||
|
projectId,
|
||||||
|
|
||||||
|
environment,
|
||||||
|
secretPath
|
||||||
});
|
});
|
||||||
closePopUp(PopUpNames.CreateSecretForm);
|
closePopUp(PopUpNames.CreateSecretForm);
|
||||||
reset();
|
reset();
|
||||||
|
return;
|
||||||
createNotification({
|
|
||||||
type: isProtectedBranch ? "info" : "success",
|
|
||||||
text: isProtectedBranch
|
|
||||||
? "Requested changes have been sent for review"
|
|
||||||
: "Successfully created secret"
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Failed to create secret"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
await createSecretV3({
|
||||||
|
environment,
|
||||||
|
projectId,
|
||||||
|
secretPath,
|
||||||
|
secretKey: key,
|
||||||
|
secretValue: value || "",
|
||||||
|
secretComment: "",
|
||||||
|
type: SecretType.Shared,
|
||||||
|
tagIds: tags?.map((el) => el.value)
|
||||||
|
});
|
||||||
|
closePopUp(PopUpNames.CreateSecretForm);
|
||||||
|
reset();
|
||||||
|
|
||||||
|
createNotification({
|
||||||
|
type: isProtectedBranch ? "info" : "success",
|
||||||
|
text: isProtectedBranch
|
||||||
|
? "Requested changes have been sent for review"
|
||||||
|
: "Successfully created secret"
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePaste = (e: ClipboardEvent<HTMLInputElement>) => {
|
const handlePaste = (e: ClipboardEvent<HTMLInputElement>) => {
|
||||||
|
|||||||
@@ -293,174 +293,166 @@ export const SecretListView = ({
|
|||||||
isSameTags &&
|
isSameTags &&
|
||||||
isSameRecipients;
|
isSameRecipients;
|
||||||
|
|
||||||
try {
|
// personal secret change
|
||||||
// personal secret change
|
let personalAction = false;
|
||||||
let personalAction = false;
|
if (overrideAction === "deleted") {
|
||||||
if (overrideAction === "deleted") {
|
await handleSecretOperation("delete", SecretType.Personal, oldKey, {
|
||||||
await handleSecretOperation("delete", SecretType.Personal, oldKey, {
|
secretId: orgSecret.idOverride
|
||||||
secretId: orgSecret.idOverride
|
});
|
||||||
});
|
personalAction = true;
|
||||||
personalAction = true;
|
} else if (overrideAction && idOverride) {
|
||||||
} else if (overrideAction && idOverride) {
|
await handleSecretOperation("update", SecretType.Personal, oldKey, {
|
||||||
await handleSecretOperation("update", SecretType.Personal, oldKey, {
|
value: valueOverride,
|
||||||
value: valueOverride,
|
newKey: hasKeyChanged ? key : undefined,
|
||||||
newKey: hasKeyChanged ? key : undefined,
|
secretId: orgSecret.idOverride,
|
||||||
secretId: orgSecret.idOverride,
|
skipMultilineEncoding: modSecret.skipMultilineEncoding
|
||||||
skipMultilineEncoding: modSecret.skipMultilineEncoding
|
});
|
||||||
});
|
personalAction = true;
|
||||||
personalAction = true;
|
} else if (overrideAction) {
|
||||||
} else if (overrideAction) {
|
await handleSecretOperation("create", SecretType.Personal, oldKey, {
|
||||||
await handleSecretOperation("create", SecretType.Personal, oldKey, {
|
value: valueOverride
|
||||||
value: valueOverride
|
});
|
||||||
});
|
personalAction = true;
|
||||||
personalAction = true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// shared secret change
|
// shared secret change
|
||||||
if (!isSharedSecUnchanged && !personalAction) {
|
if (!isSharedSecUnchanged && !personalAction) {
|
||||||
if (isBatchMode) {
|
if (isBatchMode) {
|
||||||
const isEditingPendingCreation = isPending && pendingAction === PendingAction.Create;
|
const isEditingPendingCreation = isPending && pendingAction === PendingAction.Create;
|
||||||
|
|
||||||
if (isEditingPendingCreation) {
|
if (isEditingPendingCreation) {
|
||||||
const updatedCreate: PendingSecretCreate = {
|
const updatedCreate: PendingSecretCreate = {
|
||||||
id: orgSecret.id,
|
id: orgSecret.id,
|
||||||
type: PendingAction.Create,
|
type: PendingAction.Create,
|
||||||
secretKey: key,
|
secretKey: key,
|
||||||
secretValue: value || "",
|
secretValue: value || "",
|
||||||
secretComment: comment || "",
|
secretComment: comment || "",
|
||||||
skipMultilineEncoding: modSecret.skipMultilineEncoding || false,
|
skipMultilineEncoding: modSecret.skipMultilineEncoding || false,
|
||||||
tags: tags?.map((tag) => ({ id: tag.id, slug: tag.name || tag.slug || "" })) || [],
|
tags: tags?.map((tag) => ({ id: tag.id, slug: tag.name || tag.slug || "" })) || [],
|
||||||
secretMetadata: secretMetadata || [],
|
secretMetadata: secretMetadata || [],
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
resourceType: "secret",
|
resourceType: "secret",
|
||||||
originalKey: oldKey
|
originalKey: oldKey
|
||||||
};
|
};
|
||||||
|
|
||||||
addPendingChange(updatedCreate, {
|
addPendingChange(updatedCreate, {
|
||||||
projectId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
secretPath
|
secretPath
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const trueOriginalSecret = getTrueOriginalSecret(
|
const trueOriginalSecret = getTrueOriginalSecret(
|
||||||
orgSecret,
|
orgSecret,
|
||||||
pendingChangesRef.current.secrets
|
pendingChangesRef.current.secrets
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateChange: PendingSecretUpdate = {
|
const updateChange: PendingSecretUpdate = {
|
||||||
id: orgSecret.id,
|
id: orgSecret.id,
|
||||||
type: PendingAction.Update,
|
type: PendingAction.Update,
|
||||||
secretKey: trueOriginalSecret.key,
|
secretKey: trueOriginalSecret.key,
|
||||||
newSecretName: key,
|
newSecretName: key,
|
||||||
originalValue: trueOriginalSecret.value,
|
originalValue: trueOriginalSecret.value,
|
||||||
secretValue: value,
|
secretValue: value,
|
||||||
originalComment: trueOriginalSecret.comment,
|
originalComment: trueOriginalSecret.comment,
|
||||||
secretComment: comment,
|
secretComment: comment,
|
||||||
originalSkipMultilineEncoding: trueOriginalSecret.skipMultilineEncoding,
|
originalSkipMultilineEncoding: trueOriginalSecret.skipMultilineEncoding,
|
||||||
skipMultilineEncoding: modSecret.skipMultilineEncoding,
|
skipMultilineEncoding: modSecret.skipMultilineEncoding,
|
||||||
originalTags:
|
originalTags:
|
||||||
trueOriginalSecret.tags?.map((tag) => ({ id: tag.id, slug: tag.slug })) || [],
|
trueOriginalSecret.tags?.map((tag) => ({ id: tag.id, slug: tag.slug })) || [],
|
||||||
tags: tags?.map((tag) => ({ id: tag.id, slug: tag.name || tag.slug || "" })) || [],
|
tags: tags?.map((tag) => ({ id: tag.id, slug: tag.name || tag.slug || "" })) || [],
|
||||||
originalSecretMetadata: trueOriginalSecret.secretMetadata || [],
|
originalSecretMetadata: trueOriginalSecret.secretMetadata || [],
|
||||||
secretMetadata: secretMetadata || [],
|
secretMetadata: secretMetadata || [],
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
resourceType: "secret",
|
resourceType: "secret",
|
||||||
existingSecret: orgSecret
|
existingSecret: orgSecret
|
||||||
};
|
};
|
||||||
|
|
||||||
addPendingChange(updateChange, {
|
addPendingChange(updateChange, {
|
||||||
projectId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
secretPath
|
secretPath
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (!isReminderEvent) {
|
|
||||||
handlePopUpClose("secretDetail");
|
|
||||||
}
|
|
||||||
if (cb) cb();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await handleSecretOperation("update", SecretType.Shared, oldKey, {
|
if (!isReminderEvent) {
|
||||||
value,
|
handlePopUpClose("secretDetail");
|
||||||
tags: tagIds,
|
}
|
||||||
comment,
|
|
||||||
reminderRepeatDays,
|
|
||||||
reminderNote,
|
|
||||||
reminderRecipients,
|
|
||||||
secretId: orgSecret.id,
|
|
||||||
newKey: hasKeyChanged ? key : undefined,
|
|
||||||
skipMultilineEncoding: modSecret.skipMultilineEncoding,
|
|
||||||
secretMetadata,
|
|
||||||
isRotatedSecret: orgSecret.isRotatedSecret,
|
|
||||||
secretValueHidden
|
|
||||||
});
|
|
||||||
if (cb) cb();
|
if (cb) cb();
|
||||||
}
|
return;
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: dashboardKeys.getDashboardSecrets({
|
|
||||||
projectId,
|
|
||||||
secretPath
|
|
||||||
})
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: secretSnapshotKeys.list({
|
|
||||||
projectId,
|
|
||||||
environment,
|
|
||||||
directory: secretPath
|
|
||||||
})
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: secretSnapshotKeys.count({
|
|
||||||
projectId,
|
|
||||||
environment,
|
|
||||||
directory: secretPath
|
|
||||||
})
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: commitKeys.count({ projectId, environment, directory: secretPath })
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: commitKeys.history({
|
|
||||||
projectId,
|
|
||||||
environment,
|
|
||||||
directory: secretPath
|
|
||||||
})
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: secretApprovalRequestKeys.count({ projectId })
|
|
||||||
});
|
|
||||||
if (!isReminderEvent) {
|
|
||||||
handlePopUpClose("secretDetail");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let successMessage;
|
await handleSecretOperation("update", SecretType.Shared, oldKey, {
|
||||||
if (isReminderEvent) {
|
value,
|
||||||
successMessage = reminderRepeatDays
|
tags: tagIds,
|
||||||
? "Successfully saved secret reminder"
|
comment,
|
||||||
: "Successfully deleted secret reminder";
|
reminderRepeatDays,
|
||||||
} else {
|
reminderNote,
|
||||||
successMessage = "Successfully saved secrets";
|
reminderRecipients,
|
||||||
}
|
secretId: orgSecret.id,
|
||||||
|
newKey: hasKeyChanged ? key : undefined,
|
||||||
createNotification({
|
skipMultilineEncoding: modSecret.skipMultilineEncoding,
|
||||||
type: isProtectedBranch && !personalAction ? "info" : "success",
|
secretMetadata,
|
||||||
text:
|
isRotatedSecret: orgSecret.isRotatedSecret,
|
||||||
isProtectedBranch && !personalAction
|
secretValueHidden
|
||||||
? "Requested changes have been sent for review"
|
|
||||||
: successMessage
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Failed to save secret"
|
|
||||||
});
|
});
|
||||||
|
if (cb) cb();
|
||||||
}
|
}
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: dashboardKeys.getDashboardSecrets({
|
||||||
|
projectId,
|
||||||
|
secretPath
|
||||||
|
})
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretSnapshotKeys.list({
|
||||||
|
projectId,
|
||||||
|
environment,
|
||||||
|
directory: secretPath
|
||||||
|
})
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretSnapshotKeys.count({
|
||||||
|
projectId,
|
||||||
|
environment,
|
||||||
|
directory: secretPath
|
||||||
|
})
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: commitKeys.count({ projectId, environment, directory: secretPath })
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: commitKeys.history({
|
||||||
|
projectId,
|
||||||
|
environment,
|
||||||
|
directory: secretPath
|
||||||
|
})
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretApprovalRequestKeys.count({ projectId })
|
||||||
|
});
|
||||||
|
if (!isReminderEvent) {
|
||||||
|
handlePopUpClose("secretDetail");
|
||||||
|
}
|
||||||
|
|
||||||
|
let successMessage;
|
||||||
|
if (isReminderEvent) {
|
||||||
|
successMessage = reminderRepeatDays
|
||||||
|
? "Successfully saved secret reminder"
|
||||||
|
: "Successfully deleted secret reminder";
|
||||||
|
} else {
|
||||||
|
successMessage = "Successfully saved secrets";
|
||||||
|
}
|
||||||
|
|
||||||
|
createNotification({
|
||||||
|
type: isProtectedBranch && !personalAction ? "info" : "success",
|
||||||
|
text:
|
||||||
|
isProtectedBranch && !personalAction
|
||||||
|
? "Requested changes have been sent for review"
|
||||||
|
: successMessage
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[environment, secretPath, isProtectedBranch, isBatchMode, projectId, addPendingChange]
|
[environment, secretPath, isProtectedBranch, isBatchMode, projectId, addPendingChange]
|
||||||
);
|
);
|
||||||
@@ -488,75 +480,67 @@ export const SecretListView = ({
|
|||||||
value,
|
value,
|
||||||
secretValueHidden
|
secretValueHidden
|
||||||
} = popUp.deleteSecret?.data as SecretV3RawSanitized;
|
} = popUp.deleteSecret?.data as SecretV3RawSanitized;
|
||||||
try {
|
if (isBatchMode) {
|
||||||
if (isBatchMode) {
|
const deleteChange: PendingSecretDelete = {
|
||||||
const deleteChange: PendingSecretDelete = {
|
id: `${secretId}`,
|
||||||
id: `${secretId}`,
|
type: PendingAction.Delete,
|
||||||
type: PendingAction.Delete,
|
secretKey: key,
|
||||||
secretKey: key,
|
secretValue: value || "",
|
||||||
secretValue: value || "",
|
timestamp: Date.now(),
|
||||||
timestamp: Date.now(),
|
resourceType: "secret",
|
||||||
resourceType: "secret",
|
secretValueHidden
|
||||||
secretValueHidden
|
};
|
||||||
};
|
|
||||||
|
|
||||||
addPendingChange(deleteChange, {
|
addPendingChange(deleteChange, {
|
||||||
projectId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
secretPath
|
secretPath
|
||||||
});
|
});
|
||||||
|
|
||||||
handlePopUpClose("deleteSecret");
|
|
||||||
handlePopUpClose("secretDetail");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await handleSecretOperation("delete", SecretType.Shared, key, { secretId });
|
|
||||||
// wrap this in another function and then reuse
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: dashboardKeys.getDashboardSecrets({ projectId, secretPath })
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: secretSnapshotKeys.list({
|
|
||||||
projectId,
|
|
||||||
environment,
|
|
||||||
directory: secretPath
|
|
||||||
})
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: secretSnapshotKeys.count({
|
|
||||||
projectId,
|
|
||||||
environment,
|
|
||||||
directory: secretPath
|
|
||||||
})
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: commitKeys.count({ projectId, environment, directory: secretPath })
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: commitKeys.history({ projectId, environment, directory: secretPath })
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: secretApprovalRequestKeys.count({ projectId })
|
|
||||||
});
|
|
||||||
handlePopUpClose("deleteSecret");
|
handlePopUpClose("deleteSecret");
|
||||||
handlePopUpClose("secretDetail");
|
handlePopUpClose("secretDetail");
|
||||||
createNotification({
|
return;
|
||||||
type: isProtectedBranch ? "info" : "success",
|
|
||||||
text: isProtectedBranch
|
|
||||||
? "Requested changes have been sent for review"
|
|
||||||
: "Successfully deleted secret"
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Failed to delete secret"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await handleSecretOperation("delete", SecretType.Shared, key, { secretId });
|
||||||
|
// wrap this in another function and then reuse
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: dashboardKeys.getDashboardSecrets({ projectId, secretPath })
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretKeys.getProjectSecret({ projectId, environment, secretPath })
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretSnapshotKeys.list({
|
||||||
|
projectId,
|
||||||
|
environment,
|
||||||
|
directory: secretPath
|
||||||
|
})
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretSnapshotKeys.count({
|
||||||
|
projectId,
|
||||||
|
environment,
|
||||||
|
directory: secretPath
|
||||||
|
})
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: commitKeys.count({ projectId, environment, directory: secretPath })
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: commitKeys.history({ projectId, environment, directory: secretPath })
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretApprovalRequestKeys.count({ projectId })
|
||||||
|
});
|
||||||
|
handlePopUpClose("deleteSecret");
|
||||||
|
handlePopUpClose("secretDetail");
|
||||||
|
createNotification({
|
||||||
|
type: isProtectedBranch ? "info" : "success",
|
||||||
|
text: isProtectedBranch
|
||||||
|
? "Requested changes have been sent for review"
|
||||||
|
: "Successfully deleted secret"
|
||||||
|
});
|
||||||
}, [
|
}, [
|
||||||
(popUp.deleteSecret?.data as SecretV3RawSanitized)?.key,
|
(popUp.deleteSecret?.data as SecretV3RawSanitized)?.key,
|
||||||
environment,
|
environment,
|
||||||
|
|||||||
@@ -13,26 +13,18 @@ export const AutoCapitalizationSection = () => {
|
|||||||
const { mutateAsync } = useUpdateProject();
|
const { mutateAsync } = useUpdateProject();
|
||||||
|
|
||||||
const handleToggleCapitalizationToggle = async (state: boolean) => {
|
const handleToggleCapitalizationToggle = async (state: boolean) => {
|
||||||
try {
|
if (!currentProject?.id) return;
|
||||||
if (!currentProject?.id) return;
|
|
||||||
|
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
projectId: currentProject.id,
|
projectId: currentProject.id,
|
||||||
autoCapitalization: state
|
autoCapitalization: state
|
||||||
});
|
});
|
||||||
|
|
||||||
const text = `Successfully ${state ? "enabled" : "disabled"} auto capitalization`;
|
const text = `Successfully ${state ? "enabled" : "disabled"} auto capitalization`;
|
||||||
createNotification({
|
createNotification({
|
||||||
text,
|
text,
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to update auto capitalization",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -124,17 +124,13 @@ const LoadBackupModal = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
await loadKmsBackup(backupContent);
|
||||||
await loadKmsBackup(backupContent);
|
createNotification({
|
||||||
createNotification({
|
text: "Successfully loaded KMS backup",
|
||||||
text: "Successfully loaded KMS backup",
|
type: "success"
|
||||||
type: "success"
|
});
|
||||||
});
|
|
||||||
|
|
||||||
onOpenChange(false);
|
onOpenChange(false);
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseFile = (file?: File) => {
|
const parseFile = (file?: File) => {
|
||||||
@@ -245,20 +241,16 @@ export const EncryptionTab = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onUpdateProjectKms = async (data: TForm) => {
|
const onUpdateProjectKms = async (data: TForm) => {
|
||||||
try {
|
await updateProjectKms(
|
||||||
await updateProjectKms(
|
data.kmsKeyId === INTERNAL_KMS_KEY_ID
|
||||||
data.kmsKeyId === INTERNAL_KMS_KEY_ID
|
? { type: KmsType.Internal }
|
||||||
? { type: KmsType.Internal }
|
: { type: KmsType.External, kmsId: data.kmsKeyId }
|
||||||
: { type: KmsType.External, kmsId: data.kmsKeyId }
|
);
|
||||||
);
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully updated project KMS",
|
text: "Successfully updated project KMS",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -36,28 +36,20 @@ const Content = ({ onComplete }: ContentProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onFormSubmit = async ({ environmentName, environmentSlug }: FormData) => {
|
const onFormSubmit = async ({ environmentName, environmentSlug }: FormData) => {
|
||||||
try {
|
if (!currentProject?.id) return;
|
||||||
if (!currentProject?.id) return;
|
|
||||||
|
|
||||||
const env = await mutateAsync({
|
const env = await mutateAsync({
|
||||||
projectId: currentProject.id,
|
projectId: currentProject.id,
|
||||||
name: environmentName,
|
name: environmentName,
|
||||||
slug: environmentSlug
|
slug: environmentSlug
|
||||||
});
|
});
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully created environment",
|
text: "Successfully created environment",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
onComplete(env);
|
onComplete(env);
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to create environment",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -33,29 +33,21 @@ export const UpdateEnvironmentModal = ({ popUp, handlePopUpClose, handlePopUpTog
|
|||||||
const oldEnvId = (popUp?.updateEnv?.data as { id: string })?.id;
|
const oldEnvId = (popUp?.updateEnv?.data as { id: string })?.id;
|
||||||
|
|
||||||
const onFormSubmit = async ({ name, slug }: FormData) => {
|
const onFormSubmit = async ({ name, slug }: FormData) => {
|
||||||
try {
|
if (!currentProject?.id) return;
|
||||||
if (!currentProject?.id) return;
|
|
||||||
|
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
projectId: currentProject.id,
|
projectId: currentProject.id,
|
||||||
name,
|
name,
|
||||||
slug,
|
slug,
|
||||||
id: oldEnvId
|
id: oldEnvId
|
||||||
});
|
});
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully updated environment",
|
text: "Successfully updated environment",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
handlePopUpClose("updateEnv");
|
handlePopUpClose("updateEnv");
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to update environment",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -34,22 +34,15 @@ export const PointInTimeVersionLimitSection = () => {
|
|||||||
if (!currentProject) return null;
|
if (!currentProject) return null;
|
||||||
|
|
||||||
const handleVersionLimitSubmit = async ({ pitVersionLimit }: TForm) => {
|
const handleVersionLimitSubmit = async ({ pitVersionLimit }: TForm) => {
|
||||||
try {
|
await updateProject({
|
||||||
await updateProject({
|
pitVersionLimit,
|
||||||
pitVersionLimit,
|
projectId
|
||||||
projectId
|
});
|
||||||
});
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully updated version limit",
|
text: "Successfully updated version limit",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
} catch {
|
|
||||||
createNotification({
|
|
||||||
text: "Failed updating project's version limit",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isAdmin = hasProjectRole(ProjectMembershipRole.Admin);
|
const isAdmin = hasProjectRole(ProjectMembershipRole.Admin);
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ export const SecretSharingSection = () => {
|
|||||||
const handleToggle = async (state: boolean) => {
|
const handleToggle = async (state: boolean) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
try {
|
if (!currentProject?.id) {
|
||||||
if (!currentProject?.id) {
|
setIsLoading(false);
|
||||||
setIsLoading(false);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
try {
|
||||||
await updateProject({
|
await updateProject({
|
||||||
projectId: currentProject.id,
|
projectId: currentProject.id,
|
||||||
secretSharing: state
|
secretSharing: state
|
||||||
@@ -30,12 +30,6 @@ export const SecretSharingSection = () => {
|
|||||||
text: `Successfully ${state ? "enabled" : "disabled"} secret sharing for this project`,
|
text: `Successfully ${state ? "enabled" : "disabled"} secret sharing for this project`,
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to update secret sharing for this project",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,29 +39,21 @@ export const AddSecretTagModal = ({ popUp, handlePopUpClose, handlePopUpToggle }
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onFormSubmit = async ({ slug }: FormData) => {
|
const onFormSubmit = async ({ slug }: FormData) => {
|
||||||
try {
|
if (!currentProject?.id) return;
|
||||||
if (!currentProject?.id) return;
|
|
||||||
|
|
||||||
await createWsTag.mutateAsync({
|
await createWsTag.mutateAsync({
|
||||||
projectId: currentProject?.id,
|
projectId: currentProject?.id,
|
||||||
tagSlug: slug,
|
tagSlug: slug,
|
||||||
tagColor: ""
|
tagColor: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
handlePopUpClose("CreateSecretTag");
|
handlePopUpClose("CreateSecretTag");
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully created a tag",
|
text: "Successfully created a tag",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
reset();
|
reset();
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to create a tag",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -29,25 +29,17 @@ export const SecretTagsSection = (): JSX.Element => {
|
|||||||
const deleteWsTag = useDeleteWsTag();
|
const deleteWsTag = useDeleteWsTag();
|
||||||
|
|
||||||
const onDeleteApproved = async () => {
|
const onDeleteApproved = async () => {
|
||||||
try {
|
await deleteWsTag.mutateAsync({
|
||||||
await deleteWsTag.mutateAsync({
|
projectId: currentProject?.id || "",
|
||||||
projectId: currentProject?.id || "",
|
tagID: (popUp?.deleteTagConfirmation?.data as DeleteModalData)?.id
|
||||||
tagID: (popUp?.deleteTagConfirmation?.data as DeleteModalData)?.id
|
});
|
||||||
});
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully deleted tag",
|
text: "Successfully deleted tag",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
handlePopUpClose("deleteTagConfirmation");
|
handlePopUpClose("deleteTagConfirmation");
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to delete the tag",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -126,43 +126,35 @@ export const BitbucketConfigurePage = () => {
|
|||||||
}: TFormData) => {
|
}: TFormData) => {
|
||||||
if (!targetRepo || !targetWorkspace) return;
|
if (!targetRepo || !targetWorkspace) return;
|
||||||
|
|
||||||
try {
|
await createIntegration.mutateAsync({
|
||||||
await createIntegration.mutateAsync({
|
integrationAuthId,
|
||||||
integrationAuthId,
|
isActive: true,
|
||||||
isActive: true,
|
app: targetRepo.name,
|
||||||
app: targetRepo.name,
|
appId: targetRepo.appId,
|
||||||
appId: targetRepo.appId,
|
sourceEnvironment: sourceEnvironment.slug,
|
||||||
sourceEnvironment: sourceEnvironment.slug,
|
targetEnvironment: targetWorkspace.name,
|
||||||
targetEnvironment: targetWorkspace.name,
|
targetEnvironmentId: targetWorkspace.slug,
|
||||||
targetEnvironmentId: targetWorkspace.slug,
|
...(scope.value === BitbucketScope.Env &&
|
||||||
...(scope.value === BitbucketScope.Env &&
|
targetEnvironment && {
|
||||||
targetEnvironment && {
|
targetService: targetEnvironment.name,
|
||||||
targetService: targetEnvironment.name,
|
targetServiceId: targetEnvironment.uuid
|
||||||
targetServiceId: targetEnvironment.uuid
|
}),
|
||||||
}),
|
secretPath
|
||||||
secretPath
|
});
|
||||||
});
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
type: "success",
|
type: "success",
|
||||||
text: "Successfully created integration"
|
text: "Successfully created integration"
|
||||||
});
|
});
|
||||||
navigate({
|
navigate({
|
||||||
to: "/projects/secret-management/$projectId/integrations",
|
to: "/projects/secret-management/$projectId/integrations",
|
||||||
params: {
|
params: {
|
||||||
projectId: currentProject.id
|
projectId: currentProject.id
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Failed to create integration"
|
|
||||||
});
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -73,51 +73,43 @@ export const CircleCIConfigurePage = () => {
|
|||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const onSubmit = async (data: TFormData) => {
|
const onSubmit = async (data: TFormData) => {
|
||||||
try {
|
if (data.scope === CircleCiScope.Context) {
|
||||||
if (data.scope === CircleCiScope.Context) {
|
await mutateAsync({
|
||||||
await mutateAsync({
|
scope: data.scope,
|
||||||
scope: data.scope,
|
integrationAuthId,
|
||||||
integrationAuthId,
|
isActive: true,
|
||||||
isActive: true,
|
sourceEnvironment: data.sourceEnvironment.slug,
|
||||||
sourceEnvironment: data.sourceEnvironment.slug,
|
app: data.targetContext.name,
|
||||||
app: data.targetContext.name,
|
appId: data.targetContext.id,
|
||||||
appId: data.targetContext.id,
|
owner: data.targetOrg.name,
|
||||||
owner: data.targetOrg.name,
|
secretPath: data.secretPath
|
||||||
secretPath: data.secretPath
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await mutateAsync({
|
|
||||||
scope: data.scope,
|
|
||||||
integrationAuthId,
|
|
||||||
isActive: true,
|
|
||||||
app: data.targetProject.name, // project name
|
|
||||||
owner: data.targetOrg.name, // organization name
|
|
||||||
appId: data.targetProject.id, // project id (used for syncing)
|
|
||||||
sourceEnvironment: data.sourceEnvironment.slug,
|
|
||||||
secretPath: data.secretPath
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
type: "success",
|
|
||||||
text: "Successfully created integration"
|
|
||||||
});
|
});
|
||||||
navigate({
|
} else {
|
||||||
to: "/projects/secret-management/$projectId/integrations",
|
await mutateAsync({
|
||||||
params: {
|
scope: data.scope,
|
||||||
projectId: currentProject.id
|
integrationAuthId,
|
||||||
},
|
isActive: true,
|
||||||
search: {
|
app: data.targetProject.name, // project name
|
||||||
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
owner: data.targetOrg.name, // organization name
|
||||||
}
|
appId: data.targetProject.id, // project id (used for syncing)
|
||||||
|
sourceEnvironment: data.sourceEnvironment.slug,
|
||||||
|
secretPath: data.secretPath
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Failed to create integration"
|
|
||||||
});
|
|
||||||
console.error(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createNotification({
|
||||||
|
type: "success",
|
||||||
|
text: "Successfully created integration"
|
||||||
|
});
|
||||||
|
navigate({
|
||||||
|
to: "/projects/secret-management/$projectId/integrations",
|
||||||
|
params: {
|
||||||
|
projectId: currentProject.id
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isCircleCIOrganizationsLoading)
|
if (isCircleCIOrganizationsLoading)
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
@@ -102,19 +100,7 @@ export const CloudflarePagesConfigurePage = () => {
|
|||||||
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch {
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
let errorMessage: string = "Something went wrong!";
|
|
||||||
if (axios.isAxiosError(err)) {
|
|
||||||
const { message } = err?.response?.data as { message: string };
|
|
||||||
errorMessage = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
text: errorMessage,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import { Button, Card, CardTitle, FormControl, Select, SelectItem } from "@app/components/v2";
|
import { Button, Card, CardTitle, FormControl, Select, SelectItem } from "@app/components/v2";
|
||||||
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
||||||
import { ROUTE_PATHS } from "@app/const/routes";
|
import { ROUTE_PATHS } from "@app/const/routes";
|
||||||
@@ -75,19 +73,7 @@ export const CloudflareWorkersConfigurePage = () => {
|
|||||||
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch {
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
let errorMessage: string = "Something went wrong!";
|
|
||||||
if (axios.isAxiosError(err)) {
|
|
||||||
const { message } = err?.response?.data as { message: string };
|
|
||||||
errorMessage = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
text: errorMessage,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,49 +55,45 @@ export const DatabricksConfigurePage = () => {
|
|||||||
const [secretPath, setSecretPath] = useState("/");
|
const [secretPath, setSecretPath] = useState("/");
|
||||||
|
|
||||||
const handleButtonClick = async () => {
|
const handleButtonClick = async () => {
|
||||||
try {
|
if (!integrationAuth?.id) return;
|
||||||
if (!integrationAuth?.id) return;
|
|
||||||
|
|
||||||
if (!targetScope) {
|
if (!targetScope) {
|
||||||
createNotification({
|
createNotification({
|
||||||
type: "error",
|
type: "error",
|
||||||
text: "Please select a scope"
|
text: "Please select a scope"
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedScope = integrationAuthScopes?.find(
|
|
||||||
(integrationAuthScope) => integrationAuthScope.name === targetScope
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!selectedScope) {
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: "Invalid scope selected"
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await mutateAsync({
|
|
||||||
integrationAuthId: integrationAuth?.id,
|
|
||||||
isActive: true,
|
|
||||||
app: selectedScope.name, // scope name
|
|
||||||
sourceEnvironment: selectedSourceEnvironment,
|
|
||||||
secretPath
|
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
navigate({
|
|
||||||
to: "/projects/secret-management/$projectId/integrations",
|
|
||||||
params: {
|
|
||||||
projectId: currentProject.id
|
|
||||||
},
|
|
||||||
search: {
|
|
||||||
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectedScope = integrationAuthScopes?.find(
|
||||||
|
(integrationAuthScope) => integrationAuthScope.name === targetScope
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!selectedScope) {
|
||||||
|
createNotification({
|
||||||
|
type: "error",
|
||||||
|
text: "Invalid scope selected"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await mutateAsync({
|
||||||
|
integrationAuthId: integrationAuth?.id,
|
||||||
|
isActive: true,
|
||||||
|
app: selectedScope.name, // scope name
|
||||||
|
sourceEnvironment: selectedSourceEnvironment,
|
||||||
|
secretPath
|
||||||
|
});
|
||||||
|
|
||||||
|
navigate({
|
||||||
|
to: "/projects/secret-management/$projectId/integrations",
|
||||||
|
params: {
|
||||||
|
projectId: currentProject.id
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return integrationAuth && selectedSourceEnvironment && integrationAuthScopes ? (
|
return integrationAuth && selectedSourceEnvironment && integrationAuthScopes ? (
|
||||||
|
|||||||
@@ -12,12 +12,10 @@ import {
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||||
import axios from "axios";
|
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
import { z, ZodIssueCode } from "zod";
|
import { z, ZodIssueCode } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
@@ -275,19 +273,7 @@ export const GithubConfigurePage = () => {
|
|||||||
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch {
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
let errorMessage: string = "Something went wrong!";
|
|
||||||
if (axios.isAxiosError(err)) {
|
|
||||||
const { message } = err?.response?.data as { message: string };
|
|
||||||
errorMessage = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
text: errorMessage,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,10 +4,8 @@ import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-sv
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { useNavigate } from "@tanstack/react-router";
|
import { useNavigate } from "@tanstack/react-router";
|
||||||
import axios from "axios";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import { Button, Card, CardBody, CardTitle, FormControl, Input } from "@app/components/v2";
|
import { Button, Card, CardBody, CardTitle, FormControl, Input } from "@app/components/v2";
|
||||||
import { useProject } from "@app/context";
|
import { useProject } from "@app/context";
|
||||||
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
|
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
|
||||||
@@ -41,37 +39,23 @@ export const HashicorpVaultAuthorizePage = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleFormSubmit = async (formData: TForm) => {
|
const handleFormSubmit = async (formData: TForm) => {
|
||||||
try {
|
const integrationAuth = await mutateAsync({
|
||||||
const integrationAuth = await mutateAsync({
|
workspaceId: currentProject.id,
|
||||||
workspaceId: currentProject.id,
|
integration: "hashicorp-vault",
|
||||||
integration: "hashicorp-vault",
|
accessId: formData.vaultRoleID,
|
||||||
accessId: formData.vaultRoleID,
|
accessToken: formData.vaultSecretID,
|
||||||
accessToken: formData.vaultSecretID,
|
url: formData.vaultURL,
|
||||||
url: formData.vaultURL,
|
namespace: formData.vaultNamespace
|
||||||
namespace: formData.vaultNamespace
|
});
|
||||||
});
|
navigate({
|
||||||
navigate({
|
to: "/projects/secret-management/$projectId/integrations/hashicorp-vault/create",
|
||||||
to: "/projects/secret-management/$projectId/integrations/hashicorp-vault/create",
|
params: {
|
||||||
params: {
|
projectId: currentProject.id
|
||||||
projectId: currentProject.id
|
},
|
||||||
},
|
search: {
|
||||||
search: {
|
integrationAuthId: integrationAuth.id
|
||||||
integrationAuthId: integrationAuth.id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
let errorMessage: string = "Something went wrong!";
|
|
||||||
if (axios.isAxiosError(err)) {
|
|
||||||
const { message } = err?.response?.data as { message: string };
|
|
||||||
errorMessage = message;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
createNotification({
|
|
||||||
text: errorMessage,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,10 +10,8 @@ import {
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||||
import axios from "axios";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
@@ -90,38 +88,24 @@ export const HashicorpVaultConfigurePage = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleFormSubmit = async (formData: TForm) => {
|
const handleFormSubmit = async (formData: TForm) => {
|
||||||
try {
|
if (!integrationAuth?.id) return;
|
||||||
if (!integrationAuth?.id) return;
|
await mutateAsync({
|
||||||
await mutateAsync({
|
integrationAuthId: integrationAuth?.id,
|
||||||
integrationAuthId: integrationAuth?.id,
|
isActive: true,
|
||||||
isActive: true,
|
app: formData.vaultEnginePath,
|
||||||
app: formData.vaultEnginePath,
|
sourceEnvironment: formData.selectedSourceEnvironment,
|
||||||
sourceEnvironment: formData.selectedSourceEnvironment,
|
path: formData.vaultSecretPath,
|
||||||
path: formData.vaultSecretPath,
|
secretPath: formData.secretPath
|
||||||
secretPath: formData.secretPath
|
});
|
||||||
});
|
navigate({
|
||||||
navigate({
|
to: "/projects/secret-management/$projectId/integrations",
|
||||||
to: "/projects/secret-management/$projectId/integrations",
|
params: {
|
||||||
params: {
|
projectId: currentProject.id
|
||||||
projectId: currentProject.id
|
},
|
||||||
},
|
search: {
|
||||||
search: {
|
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
||||||
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
let errorMessage: string = "Something went wrong!";
|
|
||||||
if (axios.isAxiosError(err)) {
|
|
||||||
const { message } = err?.response?.data as { message: string };
|
|
||||||
errorMessage = message;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
createNotification({
|
|
||||||
text: errorMessage,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return integrationAuth ? (
|
return integrationAuth ? (
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
|||||||
import { useNavigate } from "@tanstack/react-router";
|
import { useNavigate } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
|
||||||
import { Button, Card, CardTitle, FormControl, Input } from "@app/components/v2";
|
import { Button, Card, CardTitle, FormControl, Input } from "@app/components/v2";
|
||||||
import { useProject } from "@app/context";
|
import { useProject } from "@app/context";
|
||||||
import { removeTrailingSlash } from "@app/helpers/string";
|
import { removeTrailingSlash } from "@app/helpers/string";
|
||||||
@@ -29,30 +28,22 @@ export const OctopusDeployAuthorizePage = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = async ({ instanceUrl, apiKey }: TForm) => {
|
const onSubmit = async ({ instanceUrl, apiKey }: TForm) => {
|
||||||
try {
|
const integrationAuth = await mutateAsync({
|
||||||
const integrationAuth = await mutateAsync({
|
workspaceId: currentProject.id,
|
||||||
workspaceId: currentProject.id,
|
integration: "octopus-deploy",
|
||||||
integration: "octopus-deploy",
|
url: removeTrailingSlash(instanceUrl),
|
||||||
url: removeTrailingSlash(instanceUrl),
|
accessToken: apiKey
|
||||||
accessToken: apiKey
|
});
|
||||||
});
|
|
||||||
|
|
||||||
navigate({
|
navigate({
|
||||||
to: "/projects/secret-management/$projectId/integrations/octopus-deploy/create",
|
to: "/projects/secret-management/$projectId/integrations/octopus-deploy/create",
|
||||||
params: {
|
params: {
|
||||||
projectId: currentProject.id
|
projectId: currentProject.id
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
integrationAuthId: integrationAuth.id
|
integrationAuthId: integrationAuth.id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err: any) {
|
|
||||||
createNotification({
|
|
||||||
type: "error",
|
|
||||||
text: err.message ?? "Error authorizing integration"
|
|
||||||
});
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -107,49 +107,41 @@ export const OctopusDeployConfigurePage = () => {
|
|||||||
targetRoles,
|
targetRoles,
|
||||||
scope
|
scope
|
||||||
}: TFormData) => {
|
}: TFormData) => {
|
||||||
try {
|
await createIntegration.mutateAsync({
|
||||||
await createIntegration.mutateAsync({
|
integrationAuthId,
|
||||||
integrationAuthId,
|
isActive: true,
|
||||||
isActive: true,
|
scope,
|
||||||
scope,
|
app: targetResource.name,
|
||||||
app: targetResource.name,
|
appId: targetResource.appId,
|
||||||
appId: targetResource.appId,
|
targetEnvironment: targetSpace.Name,
|
||||||
targetEnvironment: targetSpace.Name,
|
targetEnvironmentId: targetSpace.Id,
|
||||||
targetEnvironmentId: targetSpace.Id,
|
metadata: {
|
||||||
metadata: {
|
octopusDeployScopeValues: {
|
||||||
octopusDeployScopeValues: {
|
Environment: targetEnvironments?.map(({ Id }) => Id),
|
||||||
Environment: targetEnvironments?.map(({ Id }) => Id),
|
Action: targetActions?.map(({ Id }) => Id),
|
||||||
Action: targetActions?.map(({ Id }) => Id),
|
Channel: targetChannels?.map(({ Id }) => Id),
|
||||||
Channel: targetChannels?.map(({ Id }) => Id),
|
ProcessOwner: targetProcesses?.map(({ Id }) => Id),
|
||||||
ProcessOwner: targetProcesses?.map(({ Id }) => Id),
|
Role: targetRoles?.map(({ Id }) => Id),
|
||||||
Role: targetRoles?.map(({ Id }) => Id),
|
Machine: targetMachines?.map(({ Id }) => Id)
|
||||||
Machine: targetMachines?.map(({ Id }) => Id)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sourceEnvironment: sourceEnvironment.slug,
|
|
||||||
secretPath
|
|
||||||
});
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
type: "success",
|
|
||||||
text: "Successfully created integration"
|
|
||||||
});
|
|
||||||
navigate({
|
|
||||||
to: "/projects/secret-management/$projectId/integrations",
|
|
||||||
params: {
|
|
||||||
projectId: currentProject.id
|
|
||||||
},
|
|
||||||
search: {
|
|
||||||
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
} catch (err) {
|
sourceEnvironment: sourceEnvironment.slug,
|
||||||
createNotification({
|
secretPath
|
||||||
type: "error",
|
});
|
||||||
text: "Failed to create integration"
|
|
||||||
});
|
createNotification({
|
||||||
console.error(err);
|
type: "success",
|
||||||
}
|
text: "Successfully created integration"
|
||||||
|
});
|
||||||
|
navigate({
|
||||||
|
to: "/projects/secret-management/$projectId/integrations",
|
||||||
|
params: {
|
||||||
|
projectId: currentProject.id
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
selectedTab: IntegrationsListPageTabs.NativeIntegrations
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -83,23 +83,14 @@ export const ChangeEmailSection = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
await requestEmailChangeOTP({ newEmail });
|
||||||
await requestEmailChangeOTP({ newEmail });
|
setPendingEmail(newEmail);
|
||||||
setPendingEmail(newEmail);
|
setIsOTPModalOpen(true);
|
||||||
setIsOTPModalOpen(true);
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Verification code sent to your new email address. Check your inbox!",
|
text: "Verification code sent to your new email address. Check your inbox!",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
} catch (err: any) {
|
|
||||||
console.error(err);
|
|
||||||
const errorMessage = err?.response?.data?.message || "Failed to send verification code";
|
|
||||||
createNotification({
|
|
||||||
text: errorMessage,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const [typedOTP, setTypedOTP] = useState("");
|
const [typedOTP, setTypedOTP] = useState("");
|
||||||
@@ -135,8 +126,6 @@ export const ChangeEmailSection = () => {
|
|||||||
navigate({ to: "/login" });
|
navigate({ to: "/login" });
|
||||||
}, 2000);
|
}, 2000);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
const errorMessage = err?.response?.data?.message || "Invalid verification code";
|
const errorMessage = err?.response?.data?.message || "Invalid verification code";
|
||||||
if (errorMessage.includes("Invalid verification code")) {
|
if (errorMessage.includes("Invalid verification code")) {
|
||||||
// Reset to email step so user must request new OTP
|
// Reset to email step so user must request new OTP
|
||||||
@@ -149,11 +138,6 @@ export const ChangeEmailSection = () => {
|
|||||||
text: "Invalid verification code. Please request a new one.",
|
text: "Invalid verification code. Please request a new one.",
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
createNotification({
|
|
||||||
text: errorMessage,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -97,21 +97,13 @@ export const ChangePasswordSection = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onSetupPassword = async () => {
|
const onSetupPassword = async () => {
|
||||||
try {
|
await sendSetupPasswordEmail.mutateAsync();
|
||||||
await sendSetupPasswordEmail.mutateAsync();
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
title: "Password setup verification email sent",
|
title: "Password setup verification email sent",
|
||||||
text: "Check your email to confirm password setup",
|
text: "Check your email to confirm password setup",
|
||||||
type: "info"
|
type: "info"
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to send password setup email",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -15,23 +15,15 @@ export const DeleteAccountSection = () => {
|
|||||||
const { mutateAsync: deleteUserMutateAsync, isPending } = useDeleteMe();
|
const { mutateAsync: deleteUserMutateAsync, isPending } = useDeleteMe();
|
||||||
|
|
||||||
const handleDeleteAccountSubmit = async () => {
|
const handleDeleteAccountSubmit = async () => {
|
||||||
try {
|
await deleteUserMutateAsync();
|
||||||
await deleteUserMutateAsync();
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully deleted account",
|
text: "Successfully deleted account",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
navigate({ to: "/login" });
|
navigate({ to: "/login" });
|
||||||
handlePopUpClose("deleteAccount");
|
handlePopUpClose("deleteAccount");
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to delete account",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -84,49 +84,27 @@ export const MFASection = () => {
|
|||||||
}, [totpRegistration, showMobileAuthSetup]);
|
}, [totpRegistration, showMobileAuthSetup]);
|
||||||
|
|
||||||
const handleTotpDeletion = async () => {
|
const handleTotpDeletion = async () => {
|
||||||
try {
|
await deleteTotpConfiguration();
|
||||||
await deleteTotpConfiguration();
|
|
||||||
|
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
selectedMfaMethod: MfaMethod.EMAIL
|
selectedMfaMethod: MfaMethod.EMAIL
|
||||||
});
|
});
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully deleted mobile authenticator and switched to email authentication",
|
text: "Successfully deleted mobile authenticator and switched to email authentication",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
handlePopUpClose("deleteTotpConfig");
|
handlePopUpClose("deleteTotpConfig");
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
const error = err as any;
|
|
||||||
const text = error?.response?.data?.message ?? "Failed to delete mobile authenticator";
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
text,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGenerateMoreRecoveryCodes = async () => {
|
const handleGenerateMoreRecoveryCodes = async () => {
|
||||||
try {
|
await createTotpRecoveryCodes();
|
||||||
await createTotpRecoveryCodes();
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully generated new recovery codes",
|
text: "Successfully generated new recovery codes",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
const error = err as any;
|
|
||||||
const text = error?.response?.data?.message ?? "Failed to generate new recovery codes";
|
|
||||||
|
|
||||||
createNotification({
|
|
||||||
text,
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFormDataChange = async (field: string, value: any) => {
|
const handleFormDataChange = async (field: string, value: any) => {
|
||||||
@@ -200,10 +178,6 @@ export const MFASection = () => {
|
|||||||
|
|
||||||
await queryClient.invalidateQueries({ queryKey: userKeys.totpConfiguration });
|
await queryClient.invalidateQueries({ queryKey: userKeys.totpConfiguration });
|
||||||
} catch {
|
} catch {
|
||||||
createNotification({
|
|
||||||
text: "Failed to verify TOTP code. Please try again.",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -249,12 +223,6 @@ export const MFASection = () => {
|
|||||||
setShowMobileAuthSetup(false);
|
setShowMobileAuthSetup(false);
|
||||||
setTotpCode("");
|
setTotpCode("");
|
||||||
setShouldShowRecoveryCodes.off();
|
setShouldShowRecoveryCodes.off();
|
||||||
} catch (err) {
|
|
||||||
createNotification({
|
|
||||||
text: "Something went wrong while updating two-factor authentication settings.",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
console.error(err);
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,19 +40,11 @@ export const SessionsTable = () => {
|
|||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
const handleSignOut = async (sessionId: string) => {
|
const handleSignOut = async (sessionId: string) => {
|
||||||
try {
|
await revokeMySessionById(sessionId);
|
||||||
await revokeMySessionById(sessionId);
|
createNotification({
|
||||||
createNotification({
|
text: "Session revoked successfully",
|
||||||
text: "Session revoked successfully",
|
type: "success"
|
||||||
type: "success"
|
});
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to revoke session",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePopUpClose("deleteSession");
|
handlePopUpClose("deleteSession");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,22 +27,14 @@ export const UserNameSection = (): JSX.Element => {
|
|||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
const onFormSubmit = async ({ name }: FormData) => {
|
const onFormSubmit = async ({ name }: FormData) => {
|
||||||
try {
|
if (!user?.id) return;
|
||||||
if (!user?.id) return;
|
if (name === "") return;
|
||||||
if (name === "") return;
|
|
||||||
|
|
||||||
await mutateAsync({ newName: name });
|
await mutateAsync({ newName: name });
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully renamed user",
|
text: "Successfully renamed user",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
createNotification({
|
|
||||||
text: "Failed to rename user",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user