Merge remote-tracking branch 'origin' into secret-sharing-update

This commit is contained in:
Tuan Dang
2024-07-29 15:22:13 -07:00
13 changed files with 113 additions and 26 deletions

View File

@@ -4,6 +4,30 @@ title: "Changelog"
The changelog below reflects new product developments and updates on a monthly basis.
## July 2024
- Released the official [Ruby SDK](https://infisical.com/docs/sdks/languages/ruby).
- Increased the speed and efficiency of secret operations.
- Released AWS KMS wrapping (bring your own key).
- Users can now log in to CLI via SSO in non-browser environments.
- Released [Slack Webhooks](https://infisical.com/docs/documentation/platform/webhooks).
- Added [Dynamic Secrets with MS SQL](https://infisical.com/docs/documentation/platform/dynamic-secrets/mssql).
- Redesigned and simplified the Machine Identities page.
- Added the ability to move secrets/folders to another location.
- Added [OIDC](https://infisical.com/docs/documentation/platform/identities/oidc-auth/general) support to CLI, Go SDK, and more.
- Released [Linux installer for Infisical](https://infisical.com/docs/self-hosting/deployment-options/native/standalone-binary).
## June 2024
- Released [Infisical PKI](https://infisical.com/docs/documentation/platform/pki/overview).
- Released the official [Go SDK](https://infisical.com/docs/sdks/languages/go).
- Released [OIDC Authentication method](https://infisical.com/docs/documentation/platform/identities/oidc-auth/general).
- Allowed users to configure log retention periods on self-hosted instances.
- Added [tags](https://registry.terraform.io/providers/Infisical/infisical/latest/docs/resources/secret_tag) to terraform provider.
- Released [public secret sharing](https://share.infisical.com).
- Built a [native integration with Rundeck](https://infisical.com/docs/integrations/cicd/rundeck).
- Added list view for projects in the dashboard.
- Fixed offline coding mode in CLI.
- Users are now able to leave a particular project themselves.
## May 2024
- Released [AWS](https://infisical.com/docs/documentation/platform/identities/aws-auth), [GCP](https://infisical.com/docs/documentation/platform/identities/gcp-auth), [Azure](https://infisical.com/docs/documentation/platform/identities/azure-auth), and [Kubernetes](https://infisical.com/docs/documentation/platform/identities/kubernetes-auth) Native Auth Methods.
- Added [Secret Sharing](https://infisical.com/docs/documentation/platform/secret-sharing) functionality for sharing sensitive data through encrypted links – within and outside of an organization.

View File

@@ -24,6 +24,7 @@ import {
useRevokeIdentityTokenAuthToken,
useRevokeIdentityUniversalAuthClientSecret} from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
import { TabSections } from"@app/views/Org/Types";
import { IdentityAuthMethodModal } from "../MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal";
import { IdentityModal } from "../MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityModal";
@@ -75,7 +76,7 @@ export const IdentityPage = withPermission(
});
handlePopUpClose("deleteIdentity");
router.push(`/org/${orgId}/members`);
router.push(`/org/${orgId}/members?selectedTab=${TabSections.Identities}`);
} catch (err) {
console.error(err);
const error = err as any;
@@ -154,7 +155,7 @@ export const IdentityPage = withPermission(
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => {
router.push(`/org/${orgId}/members`);
router.push(`/org/${orgId}/members?selectedTab=${TabSections.Identities}`);
}}
className="mb-4"
>

View File

@@ -10,6 +10,7 @@ import { useWorkspace } from "@app/context";
import { IdentityMembership } from "@app/hooks/api/identities/types";
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
import { TabSections } from "@app/views/Org/Types";
type Props = {
membership: IdentityMembership;
@@ -51,7 +52,7 @@ export const IdentityProjectRow = ({
key={`identity-project-membership-${id}`}
onClick={() => {
if (isAccessible) {
router.push(`/project/${project.id}/members`);
router.push(`/project/${project.id}/members?selectedTab=${TabSections.Identities}`);
return;
}

View File

@@ -1,23 +1,39 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
import { withPermission } from "@app/hoc";
import { isTabSection, TabSections } from "@app/views/Org/Types";;
import { OrgIdentityTab, OrgMembersTab, OrgRoleTabSection } from "./components";
enum TabSections {
Member = "members",
Roles = "roles",
Identities = "identities"
}
export const MembersPage = withPermission(
() => {
const router = useRouter();
const { query } = router;
const selectedTab = query.selectedTab as string;
const [activeTab, setActiveTab] = useState<TabSections>(TabSections.Member);
useEffect(() => {
if (selectedTab && isTabSection(selectedTab)) {
setActiveTab(selectedTab);
}
}, [isTabSection, selectedTab]);
const updateSelectedTab = (tab: string) => {
router.push({
pathname: router.pathname,
query: { ...router.query, selectedTab: tab },
});
}
return (
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-7xl py-6 px-6">
<p className="mr-4 mb-4 text-3xl font-semibold text-white">Organization Access Control</p>
<Tabs defaultValue={TabSections.Member}>
<Tabs value={activeTab} onValueChange={updateSelectedTab}>
<TabList>
<Tab value={TabSections.Member}>Users</Tab>
<Tab value={TabSections.Identities}>
@@ -25,7 +41,7 @@ export const MembersPage = withPermission(
<p>Machine Identities</p>
</div>
</Tab>
<Tab value={TabSections.Roles}>Organization Roles</Tab>
<Tab value={TabSections.Roles}>Organization Roles</Tab>
</TabList>
<TabPanel value={TabSections.Member}>
<OrgMembersTab />

View File

@@ -19,6 +19,7 @@ import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@a
import { withPermission } from "@app/hoc";
import { useDeleteOrgRole, useGetOrgRole } from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
import { TabSections } from "@app/views/Org/Types";
import { RoleDetailsSection, RoleModal, RolePermissionsSection } from "./components";
@@ -51,7 +52,7 @@ export const RolePage = withPermission(
});
handlePopUpClose("deleteOrgRole");
router.push(`/org/${orgId}/members`);
router.push(`/org/${orgId}/members?selectedTab=${TabSections.Roles}`);
} catch (err) {
console.error(err);
const error = err as any;
@@ -75,7 +76,7 @@ export const RolePage = withPermission(
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => {
router.push(`/org/${orgId}/members`);
router.push(`/org/${orgId}/members?selectedTab=${TabSections.Roles}`);
}}
className="mb-4"
>

View File

@@ -0,0 +1,9 @@
export enum TabSections {
Member = "members",
Roles = "roles",
Identities = "identities"
}
export const isTabSection = (value: string): value is TabSections => {
return (Object.values(TabSections) as string[]).includes(value);
}

View File

@@ -0,0 +1,3 @@
import { TabSections, isTabSection } from "./TabSections";
export { TabSections, isTabSection };

View File

@@ -29,6 +29,7 @@ import {
useUpdateOrgMembership
} from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
import { TabSections } from "@app/views/Org/Types";
import { UserDetailsSection, UserOrgMembershipModal, UserProjectsSection } from "./components";
@@ -90,7 +91,7 @@ export const UserPage = withPermission(
});
handlePopUpClose("removeMember");
router.push(`/org/${orgId}/members`);
router.push(`/org/${orgId}/members?selectedTab=${TabSections.Member}`);
} catch (err) {
console.error(err);
createNotification({
@@ -111,7 +112,7 @@ export const UserPage = withPermission(
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => {
router.push(`/org/${orgId}/members`);
router.push(`/org/${orgId}/members?selectedTab=${TabSections.Member}`);
}}
className="mb-4"
>

View File

@@ -9,6 +9,7 @@ import { useWorkspace } from "@app/context";
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
import { TWorkspaceUser } from "@app/hooks/api/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
import { TabSections } from "@app/views/Org/Types";;
type Props = {
membership: TWorkspaceUser;
@@ -47,7 +48,7 @@ export const UserProjectRow = ({
key={`user-project-membership-${id}`}
onClick={() => {
if (isAccessible) {
router.push(`/project/${project.id}/members`);
router.push(`/project/${project.id}/members?selectedTab=${TabSections.Member}`);
return;
}

View File

@@ -1,25 +1,40 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { withProjectPermission } from "@app/hoc";
import { IdentityTab, MembersTab,ProjectRoleListTab, ServiceTokenTab } from "./components";
import { TabSections, isTabSection } from '../Types';
enum TabSections {
Member = "members",
Roles = "roles",
Groups = "groups",
Identities = "identities",
ServiceTokens = "service-tokens"
}
export const MembersPage = withProjectPermission(
() => {
const router = useRouter();
const { query } = router;
const selectedTab = query.selectedTab as string;
const [activeTab, setActiveTab] = useState<TabSections>(TabSections.Member);
useEffect(() => {
if (selectedTab && isTabSection(selectedTab)) {
setActiveTab(selectedTab);
}
}, [isTabSection, selectedTab]);
const updateSelectedTab = (tab: string) => {
router.push({
pathname: router.pathname,
query: { ...router.query, selectedTab: tab },
});
}
return (
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mx-auto mb-6 w-full max-w-7xl py-6 px-6">
<p className="mr-4 mb-4 text-3xl font-semibold text-white">Project Access Control</p>
<Tabs defaultValue={TabSections.Member}>
<Tabs value={activeTab} onValueChange={updateSelectedTab}>
<TabList>
<Tab value={TabSections.Member}>Users</Tab>
<Tab value={TabSections.Identities}>

View File

@@ -21,6 +21,7 @@ import { useDeleteProjectRole,useGetProjectRoleBySlug } from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
import { RoleDetailsSection, RoleModal, RolePermissionsSection } from "./components";
import { TabSections } from '../Types';
export const RolePage = withProjectPermission(
() => {
@@ -52,7 +53,7 @@ export const RolePage = withProjectPermission(
type: "success"
});
handlePopUpClose("deleteRole");
router.push(`/project/${projectId}/members`);
router.push(`/project/${projectId}/members?selectedTab=${TabSections.Roles}`);
} catch (err) {
console.error(err);
const error = err as any;
@@ -75,7 +76,7 @@ export const RolePage = withProjectPermission(
variant="link"
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => router.push(`/project/${projectId}/members`)}
onClick={() => router.push(`/project/${projectId}/members?selectedTab=${TabSections.Roles}`)}
className="mb-4"
>
Roles

View File

@@ -0,0 +1,11 @@
export enum TabSections {
Member = "members",
Roles = "roles",
Groups = "groups",
Identities = "identities",
ServiceTokens = "service-tokens"
}
export const isTabSection = (value: string): value is TabSections => {
return (Object.values(TabSections) as string[]).includes(value);
}

View File

@@ -0,0 +1,3 @@
import { TabSections, isTabSection } from "./TabSections";
export { TabSections, isTabSection };