diff --git a/backend/src/db/migrations/20240202093209_ghost_user.ts b/backend/src/db/migrations/20240202093209_ghost_user.ts index 72181cd83..ddfdbe812 100644 --- a/backend/src/db/migrations/20240202093209_ghost_user.ts +++ b/backend/src/db/migrations/20240202093209_ghost_user.ts @@ -15,6 +15,7 @@ export async function up(knex: Knex): Promise { if (!hasProjectVersionColumn) { await knex.schema.alterTable(TableName.Project, (t) => { t.string("version").defaultTo(ProjectVersion.V1).notNullable(); + t.text("upgradeStatus").nullable(); }); } } @@ -32,6 +33,7 @@ export async function down(knex: Knex): Promise { if (hasProjectVersionColumn) { await knex.schema.alterTable(TableName.Project, (t) => { t.dropColumn("version"); + t.dropColumn("upgradeStatus"); }); } } diff --git a/backend/src/db/schemas/models.ts b/backend/src/db/schemas/models.ts index abfb67949..2b838b1bf 100644 --- a/backend/src/db/schemas/models.ts +++ b/backend/src/db/schemas/models.ts @@ -123,6 +123,24 @@ export enum ProjectUpgradeStatus { Failed = "FAILED" } +// Case study: +/* + +Q: If the upgrade status is null and the project version is V1: +A: It would mean that the project has not been attempted to be upgraded + +Q: If the upgrade status is not null (FAILED or IN_PROGRESS), we a status + +Q: if the project status is null, and the project version is v2, we should display nothing cuz its upgraded! + +*/ + +export enum ProjectUpgradeStatus { + InProgress = "IN_PROGRESS", + Completed = "Project upgrade completed.", // Will be null if completed. So a completed status is not needed + Failed = "FAILED" +} + export enum IdentityAuthMethod { Univeral = "universal-auth" } diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 22d1e2123..9444aff16 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -327,12 +327,7 @@ export const registerRoutes = async ( identityProjectDAL, identityOrgMembershipDAL, projectBotDAL, - secretDAL, - orgDAL, - secretApprovalRequestDAL, - secretApprovalSecretDAL: sarSecretDAL, projectKeyDAL, - secretVersionDAL, userDAL, projectEnvDAL, orgService, diff --git a/backend/src/services/project/project-dal.ts b/backend/src/services/project/project-dal.ts index 7d0826e12..f18542216 100644 --- a/backend/src/services/project/project-dal.ts +++ b/backend/src/services/project/project-dal.ts @@ -80,6 +80,18 @@ export const projectDALFactory = (db: TDbClient) => { } }; + const setProjectUpgradeStatus = async (projectId: string, status: ProjectUpgradeStatus) => { + try { + const data: TProjectsUpdate = { + upgradeStatus: status + } as const; + + await db(TableName.Project).where({ id: projectId }).update(data); + } catch (error) { + throw new DatabaseError({ error, name: "Set project upgrade status" }); + } + }; + const findAllProjectsByIdentity = async (identityId: string) => { try { const workspaces = await db(TableName.IdentityProjectMembership) diff --git a/backend/src/services/project/project-service.ts b/backend/src/services/project/project-service.ts index 643c8aa72..e88a5879e 100644 --- a/backend/src/services/project/project-service.ts +++ b/backend/src/services/project/project-service.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable no-console */ /* eslint-disable no-await-in-loop */ import { ForbiddenError } from "@casl/ability"; @@ -8,18 +9,10 @@ import { TLicenseServiceFactory } from "@app/ee/services/license/license-service import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; -import { TSecretApprovalRequestDALFactory } from "@app/ee/services/secret-approval-request/secret-approval-request-dal"; -import { TSecretApprovalRequestSecretDALFactory } from "@app/ee/services/secret-approval-request/secret-approval-request-secret-dal"; -import { RequestState } from "@app/ee/services/secret-approval-request/secret-approval-request-types"; import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { getConfig } from "@app/lib/config/env"; import { createSecretBlindIndex } from "@app/lib/crypto"; -import { - decryptAsymmetric, - encryptSymmetric128BitHexKeyUTF8, - infisicalSymmetricDecrypt, - infisicalSymmetricEncypt -} from "@app/lib/crypto/encryption"; +import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; import { BadRequestError, ForbiddenRequestError } from "@app/lib/errors"; import { alphaNumericNanoId } from "@app/lib/nanoid"; import { TProjectPermission } from "@app/lib/types"; @@ -27,14 +20,11 @@ import { TProjectPermission } from "@app/lib/types"; import { ActorType } from "../auth/auth-type"; import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TIdentityProjectDALFactory } from "../identity-project/identity-project-dal"; -import { TOrgDALFactory } from "../org/org-dal"; import { TOrgServiceFactory } from "../org/org-service"; import { TProjectBotDALFactory } from "../project-bot/project-bot-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectKeyDALFactory } from "../project-key/project-key-dal"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; -import { TSecretDALFactory } from "../secret/secret-dal"; -import { TSecretVersionDALFactory } from "../secret/secret-version-dal"; import { TSecretBlindIndexDALFactory } from "../secret-blind-index/secret-blind-index-dal"; import { ROOT_FOLDER_NAME, TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TUserDALFactory } from "../user/user-dal"; @@ -78,18 +68,13 @@ export const projectServiceFactory = ({ projectDAL, projectQueue, projectKeyDAL, - secretApprovalRequestDAL, - secretApprovalSecretDAL, permissionService, userDAL, folderDAL, orgService, - orgDAL, identityProjectDAL, - secretVersionDAL, projectBotDAL, identityOrgMembershipDAL, - secretDAL, secretBlindIndexDAL, projectMembershipDAL, projectEnvDAL, diff --git a/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx b/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx index cf7426cce..ec3bdd9e4 100644 --- a/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx +++ b/frontend/src/components/v2/UpgradeProjectAlert/UpgradeProjectAlert.tsx @@ -86,18 +86,18 @@ export const UpgradeProjectAlert = ({ project }: UpgradeProjectAlertProps): JSX. if (membership.role !== "admin") return null; return ( -
- -
- Upgrade your project +
+ +
+ Upgrade your project Upgrade your project version to continue receiving the latest improvements and patches. {currentStatus &&

Status: {currentStatus}

}
- -
+ +
); }; diff --git a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx index 58c34d627..d31eb3b6e 100644 --- a/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx +++ b/frontend/src/views/SecretOverviewPage/SecretOverviewPage.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import Link from "next/link"; import { useRouter } from "next/router"; @@ -14,8 +14,6 @@ import { useNotificationContext } from "@app/components/context/Notifications/No import NavHeader from "@app/components/navigation/NavHeader"; import { PermissionDeniedBanner } from "@app/components/permissions"; import { - Alert, - AlertDescription, Button, EmptyState, IconButton, @@ -40,8 +38,7 @@ import { useGetFoldersByEnv, useGetProjectSecretsAllEnv, useGetUserWsKey, - useUpdateSecretV3, - useUpgradeProject + useUpdateSecretV3 } from "@app/hooks/api"; import { ProjectVersion } from "@app/hooks/api/workspace/types"; @@ -109,7 +106,6 @@ export const SecretOverviewPage = () => { environments: userAvailableEnvs.map(({ slug }) => slug) }); - const upgradeProject = useUpgradeProject(); const { mutateAsync: createSecretV3 } = useCreateSecretV3(); const { mutateAsync: updateSecretV3 } = useUpdateSecretV3(); const { mutateAsync: deleteSecretV3 } = useDeleteSecretV3(); @@ -203,24 +199,6 @@ export const SecretOverviewPage = () => { } }; - const onUpgradeProject = useCallback(async () => { - const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY"); - - if (!PRIVATE_KEY) { - createNotification({ - type: "error", - text: "Private key not found" - }); - - return; - } - - await upgradeProject.mutateAsync({ - projectId: workspaceId, - privateKey: PRIVATE_KEY - }); - }, []); - const handleResetSearch = () => setSearchFilter(""); const handleFolderClick = (path: string) => {