diff --git a/backend/src/ee/routes/v1/org-role-router.ts b/backend/src/ee/routes/v1/org-role-router.ts
index 148a84300..3ecf6fbfd 100644
--- a/backend/src/ee/routes/v1/org-role-router.ts
+++ b/backend/src/ee/routes/v1/org-role-router.ts
@@ -19,7 +19,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
.min(1)
.trim()
.refine(
- (val) => Object.keys(OrgMembershipRole).includes(val),
+ (val) => !Object.keys(OrgMembershipRole).includes(val),
"Please choose a different slug, the slug you have entered is reserved"
)
.refine((v) => slugify(v) === v, {
diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue-fn.ts b/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue-fn.ts
index c67477bfd..5a2e478e1 100644
--- a/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue-fn.ts
+++ b/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue-fn.ts
@@ -9,6 +9,7 @@ import jmespath from "jmespath";
import knex from "knex";
import { getConfig } from "@app/lib/config/env";
+import { getDbConnectionHost } from "@app/lib/knex";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { TAssignOp, TDbProviderClients, TDirectAssignOp, THttpProviderFunction } from "../templates/types";
@@ -89,7 +90,7 @@ export const secretRotationDbFn = async ({
const appCfg = getConfig();
const ssl = ca ? { rejectUnauthorized: false, ca } : undefined;
- if (host === "localhost" || host === "127.0.0.1" || appCfg.DB_CONNECTION_URI.includes(host))
+ if (host === "localhost" || host === "127.0.0.1" || getDbConnectionHost(appCfg.DB_CONNECTION_URI) === host)
throw new Error("Invalid db host");
const db = knex({
diff --git a/backend/src/lib/knex/connection.ts b/backend/src/lib/knex/connection.ts
new file mode 100644
index 000000000..993615a0b
--- /dev/null
+++ b/backend/src/lib/knex/connection.ts
@@ -0,0 +1,11 @@
+import { URL } from "url"; // Import the URL class
+
+export const getDbConnectionHost = (urlString: string) => {
+ try {
+ const url = new URL(urlString);
+ // Split hostname and port (if provided)
+ return url.hostname.split(":")[0];
+ } catch (error) {
+ return null;
+ }
+};
diff --git a/backend/src/lib/knex/index.ts b/backend/src/lib/knex/index.ts
index 37fae624e..d78020809 100644
--- a/backend/src/lib/knex/index.ts
+++ b/backend/src/lib/knex/index.ts
@@ -4,6 +4,7 @@ import { Tables } from "knex/types/tables";
import { DatabaseError } from "../errors";
+export * from "./connection";
export * from "./join";
export * from "./select";
diff --git a/backend/src/server/plugins/swagger.ts b/backend/src/server/plugins/swagger.ts
index 1eb1a0f4e..2d7e6706c 100644
--- a/backend/src/server/plugins/swagger.ts
+++ b/backend/src/server/plugins/swagger.ts
@@ -14,13 +14,13 @@ export const fastifySwagger = fp(async (fastify) => {
version: "0.0.1"
},
servers: [
- {
- url: "http://localhost:8080",
- description: "Local server"
- },
{
url: "https://app.infisical.com",
description: "Production server"
+ },
+ {
+ url: "http://localhost:8080",
+ description: "Local server"
}
],
components: {
diff --git a/backend/src/server/routes/v2/project-router.ts b/backend/src/server/routes/v2/project-router.ts
index 7ae5b3508..3258be50a 100644
--- a/backend/src/server/routes/v2/project-router.ts
+++ b/backend/src/server/routes/v2/project-router.ts
@@ -150,8 +150,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
message: "Slug must be a valid slug"
})
.optional()
- .describe(PROJECTS.CREATE.slug),
- organizationSlug: z.string().trim().describe(PROJECTS.CREATE.organizationSlug)
+ .describe(PROJECTS.CREATE.slug)
}),
response: {
200: z.object({
@@ -166,7 +165,6 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
- orgSlug: req.body.organizationSlug,
workspaceName: req.body.projectName,
slug: req.body.slug
});
diff --git a/backend/src/services/project/project-service.ts b/backend/src/services/project/project-service.ts
index 71703a50c..5eaf081dc 100644
--- a/backend/src/services/project/project-service.ts
+++ b/backend/src/services/project/project-service.ts
@@ -92,7 +92,6 @@ export const projectServiceFactory = ({
* Create workspace. Make user the admin
* */
const createProject = async ({
- orgSlug,
actor,
actorId,
actorOrgId,
@@ -100,13 +99,7 @@ export const projectServiceFactory = ({
workspaceName,
slug: projectSlug
}: TCreateProjectDTO) => {
- if (!orgSlug) {
- throw new BadRequestError({
- message: "Must provide organization slug to create project"
- });
- }
-
- const organization = await orgDAL.findOne({ slug: orgSlug });
+ const organization = await orgDAL.findOne({ id: actorOrgId });
const { permission, membership: orgMembership } = await permissionService.getOrgPermission(
actor,
diff --git a/backend/src/services/project/project-types.ts b/backend/src/services/project/project-types.ts
index 5b2b635f2..dcd424e18 100644
--- a/backend/src/services/project/project-types.ts
+++ b/backend/src/services/project/project-types.ts
@@ -24,7 +24,6 @@ export type TCreateProjectDTO = {
actorAuthMethod: ActorAuthMethod;
actorId: string;
actorOrgId?: string;
- orgSlug: string;
workspaceName: string;
slug?: string;
};
diff --git a/docs/self-hosting/ee.mdx b/docs/self-hosting/ee.mdx
index e1f3cff40..832d99eaf 100644
--- a/docs/self-hosting/ee.mdx
+++ b/docs/self-hosting/ee.mdx
@@ -9,7 +9,7 @@ This guide walks through how you can use these paid features in Infisical.
- Start by either signing up for a free demo [here](https://infisical.com/schedule-demo) or contacting team@infisical.com to purchase a license.
+ Start by either signing up for a free demo [here](https://infisical.com/schedule-demo) or contacting sales@infisical.com to purchase a license.
Once purchased, you will be issued a license key.
@@ -25,4 +25,4 @@ This guide walks through how you can use these paid features in Infisical.
Once the license expires, Infisical will continue to run, but EE features will be disabled until the license is renewed or a new one is purchased.
-
\ No newline at end of file
+
diff --git a/frontend/src/components/signup/UserInfoStep.tsx b/frontend/src/components/signup/UserInfoStep.tsx
index a7d11d10c..c98998e35 100644
--- a/frontend/src/components/signup/UserInfoStep.tsx
+++ b/frontend/src/components/signup/UserInfoStep.tsx
@@ -196,10 +196,8 @@ export default function UserInfoStep({
const userOrgs = await fetchOrganizations();
- const orgSlug = userOrgs[0]?.slug;
const orgId = userOrgs[0]?.id;
const project = await ProjectService.initProject({
- organizationSlug: orgSlug,
projectName: "Example Project"
});
diff --git a/frontend/src/components/utilities/intercom/intercom.ts b/frontend/src/components/utilities/intercom/intercom.ts
index 56b374107..7228fceb7 100644
--- a/frontend/src/components/utilities/intercom/intercom.ts
+++ b/frontend/src/components/utilities/intercom/intercom.ts
@@ -7,6 +7,7 @@
/* eslint-disable vars-on-top */
/* eslint-disable no-var */
/* eslint-disable func-names */
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import { INTERCOMid as APPid } from "@app/components/utilities/config";
diff --git a/frontend/src/components/v2/Menu/Menu.tsx b/frontend/src/components/v2/Menu/Menu.tsx
index dd3407557..0555ef826 100644
--- a/frontend/src/components/v2/Menu/Menu.tsx
+++ b/frontend/src/components/v2/Menu/Menu.tsx
@@ -1,3 +1,4 @@
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable global-require */
diff --git a/frontend/src/helpers/project.ts b/frontend/src/helpers/project.ts
index 8379b0fa5..ff8e700a4 100644
--- a/frontend/src/helpers/project.ts
+++ b/frontend/src/helpers/project.ts
@@ -77,18 +77,11 @@ const secretsToBeAdded = [
* @param {String} obj.projectName - name of new project
* @returns {Project} project - new project
*/
-const initProjectHelper = async ({
- organizationSlug,
- projectName
-}: {
- organizationSlug: string;
- projectName: string;
-}) => {
+const initProjectHelper = async ({ projectName }: { projectName: string }) => {
// create new project
const {
data: { project }
} = await createWorkspace({
- organizationSlug,
projectName
});
diff --git a/frontend/src/hooks/api/workspace/queries.tsx b/frontend/src/hooks/api/workspace/queries.tsx
index 24a7e5794..001454233 100644
--- a/frontend/src/hooks/api/workspace/queries.tsx
+++ b/frontend/src/hooks/api/workspace/queries.tsx
@@ -199,19 +199,17 @@ export const useGetWorkspaceIntegrations = (workspaceId: string) =>
});
export const createWorkspace = ({
- organizationSlug,
projectName
}: CreateWorkspaceDTO): Promise<{ data: { project: Workspace } }> => {
- return apiRequest.post("/api/v2/workspace", { projectName, organizationSlug });
+ return apiRequest.post("/api/v2/workspace", { projectName });
};
export const useCreateWorkspace = () => {
const queryClient = useQueryClient();
return useMutation<{ data: { project: Workspace } }, {}, CreateWorkspaceDTO>({
- mutationFn: async ({ organizationSlug, projectName }) =>
+ mutationFn: async ({ projectName }) =>
createWorkspace({
- organizationSlug,
projectName
}),
onSuccess: () => {
@@ -325,7 +323,13 @@ export const useDeleteUserFromWorkspace = () => {
const queryClient = useQueryClient();
return useMutation({
- mutationFn: async ({ usernames, workspaceId }: { workspaceId: string; usernames: string[] }) => {
+ mutationFn: async ({
+ usernames,
+ workspaceId
+ }: {
+ workspaceId: string;
+ usernames: string[];
+ }) => {
const {
data: { deletedMembership }
} = await apiRequest.delete(`/api/v2/workspace/${workspaceId}/memberships`, {
@@ -391,11 +395,7 @@ export const useAddIdentityToWorkspace = () => {
export const useUpdateIdentityWorkspaceRole = () => {
const queryClient = useQueryClient();
return useMutation({
- mutationFn: async ({
- identityId,
- workspaceId,
- roles
- }:TUpdateWorkspaceIdentityRoleDTO)=> {
+ mutationFn: async ({ identityId, workspaceId, roles }: TUpdateWorkspaceIdentityRoleDTO) => {
const {
data: { identityMembership }
} = await apiRequest.patch(
diff --git a/frontend/src/hooks/api/workspace/types.ts b/frontend/src/hooks/api/workspace/types.ts
index 657b07693..f0cee7741 100644
--- a/frontend/src/hooks/api/workspace/types.ts
+++ b/frontend/src/hooks/api/workspace/types.ts
@@ -45,7 +45,6 @@ export type TGetUpgradeProjectStatusDTO = {
// mutation dto
export type CreateWorkspaceDTO = {
projectName: string;
- organizationSlug: string;
};
export type RenameWorkspaceDTO = { workspaceID: string; newWorkspaceName: string };
@@ -82,16 +81,16 @@ export type TUpdateWorkspaceUserRoleDTO = {
workspaceId: string;
roles: (
| {
- role: string;
- isTemporary?: false;
- }
+ role: string;
+ isTemporary?: false;
+ }
| {
- role: string;
- isTemporary: true;
- temporaryMode: ProjectUserMembershipTemporaryMode;
- temporaryRange: string;
- temporaryAccessStartTime: string;
- }
+ role: string;
+ isTemporary: true;
+ temporaryMode: ProjectUserMembershipTemporaryMode;
+ temporaryRange: string;
+ temporaryAccessStartTime: string;
+ }
)[];
};
@@ -100,15 +99,15 @@ export type TUpdateWorkspaceIdentityRoleDTO = {
workspaceId: string;
roles: (
| {
- role: string;
- isTemporary?: false;
- }
+ role: string;
+ isTemporary?: false;
+ }
| {
- role: string;
- isTemporary: true;
- temporaryMode: ProjectUserMembershipTemporaryMode;
- temporaryRange: string;
- temporaryAccessStartTime: string;
- }
+ role: string;
+ isTemporary: true;
+ temporaryMode: ProjectUserMembershipTemporaryMode;
+ temporaryRange: string;
+ temporaryAccessStartTime: string;
+ }
)[];
};
diff --git a/frontend/src/layouts/AdminLayout/AdminLayout.tsx b/frontend/src/layouts/AdminLayout/AdminLayout.tsx
index 539aedfd9..f806b6e79 100644
--- a/frontend/src/layouts/AdminLayout/AdminLayout.tsx
+++ b/frontend/src/layouts/AdminLayout/AdminLayout.tsx
@@ -4,6 +4,7 @@
/* eslint-disable vars-on-top */
/* eslint-disable no-var */
/* eslint-disable func-names */
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import { useTranslation } from "react-i18next";
@@ -91,7 +92,7 @@ export const AdminLayout = ({ children }: LayoutProps) => {
console.error(error);
}
};
-
+
return (
<>
diff --git a/frontend/src/layouts/AppLayout/AppLayout.tsx b/frontend/src/layouts/AppLayout/AppLayout.tsx
index e78913f6e..70a6b4326 100644
--- a/frontend/src/layouts/AppLayout/AppLayout.tsx
+++ b/frontend/src/layouts/AppLayout/AppLayout.tsx
@@ -236,7 +236,6 @@ export const AppLayout = ({ children }: LayoutProps) => {
project: { id: newProjectId }
}
} = await createWs.mutateAsync({
- organizationSlug: currentOrg.slug,
projectName: name
});
diff --git a/frontend/src/pages/login/select-organization.tsx b/frontend/src/pages/login/select-organization.tsx
index b9226343b..481b42966 100644
--- a/frontend/src/pages/login/select-organization.tsx
+++ b/frontend/src/pages/login/select-organization.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { useCallback, useEffect } from "react";
import { useTranslation } from "react-i18next";
import Head from "next/head";
@@ -54,42 +52,40 @@ export default function LoginPage() {
const handleSelectOrganization = useCallback(
async (organization: Organization) => {
+ const callbackPort = queryParams.get("callback_port");
+
if (organization.authEnforced) {
// org has an org-level auth method enabled (e.g. SAML)
// -> logout + redirect to SAML SSO
+ let samlUrl = `/api/v1/sso/redirect/saml2/organizations/${organization.slug}`;
+
+ if (callbackPort) {
+ samlUrl += `?callback_port=${callbackPort}`;
+ }
await logout.mutateAsync();
- window.open(`/api/v1/sso/redirect/saml2/organizations/${organization.slug}`);
+ window.open(samlUrl);
window.close();
return;
}
const { token } = await selectOrg.mutateAsync({ organizationId: organization.id });
- const callbackPort = queryParams.get("callback_port");
-
if (callbackPort) {
const privateKey = localStorage.getItem("PRIVATE_KEY");
- if (!privateKey) {
- createNotification({
- text: "Private key not found",
- type: "error"
- });
- }
+ let error: string | null = null;
- if (!user.email) {
- createNotification({
- text: "User email not found",
- type: "error"
- });
- }
+ if (!privateKey) error = "Private key not found";
+ if (!user.email) error = "User email not found";
+ if (!token) error = "No token found";
- if (!token) {
+ if (error) {
createNotification({
- text: "No token found",
+ text: error,
type: "error"
});
+ return;
}
const payload = {
@@ -172,33 +168,22 @@ export default function LoginPage() {
) : (
organizations.data?.map((org) => (
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
handleSelectOrganization(org)}
key={org.id}
className="group flex cursor-pointer items-center justify-between rounded-md bg-mineshaft-700 px-4 py-3 capitalize text-gray-200 shadow-md transition-colors hover:bg-mineshaft-600"
>
-
{org.name}
+
{org.name}
))
)}
-
-
diff --git a/frontend/src/pages/org/[id]/overview/index.tsx b/frontend/src/pages/org/[id]/overview/index.tsx
index b37c8ab9e..38be2f4b7 100644
--- a/frontend/src/pages/org/[id]/overview/index.tsx
+++ b/frontend/src/pages/org/[id]/overview/index.tsx
@@ -454,7 +454,12 @@ const LearningItemSquare = ({
};
const formSchema = yup.object({
- name: yup.string().required().label("Project Name").trim().max(64, "Too long, maximum length is 64 characters"),
+ name: yup
+ .string()
+ .required()
+ .label("Project Name")
+ .trim()
+ .max(64, "Too long, maximum length is 64 characters"),
addMembers: yup.bool().required().label("Add Members")
});
@@ -507,7 +512,6 @@ const OrganizationPage = withPermission(
project: { id: newProjectId }
}
} = await createWs.mutateAsync({
- organizationSlug: currentOrg.slug,
projectName: name
});
@@ -631,22 +635,21 @@ const OrganizationPage = withPermission(
{orgWorkspaces
.filter((ws) => ws?.name?.toLowerCase().includes(searchFilter.toLowerCase()))
.map((workspace) => (
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
{
+ router.push(`/project/${workspace.id}/secrets/overview`);
+ localStorage.setItem("projectData.id", workspace.id);
+ }}
key={workspace.id}
- className="min-w-72 flex h-40 flex-col justify-between rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4"
+ className="min-w-72 group flex h-40 cursor-pointer flex-col justify-between rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4"
>
{workspace.name}
{workspace.environments?.length || 0} environments
-