Merge remote-tracking branch 'origin' into groups-phase-2b

This commit is contained in:
Tuan Dang
2024-04-22 14:21:21 -07:00
7 changed files with 54 additions and 39 deletions
@@ -157,7 +157,13 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
response: { response: {
200: z.object({ 200: z.object({
data: z.object({ data: z.object({
membership: ProjectMembershipsSchema, membership: ProjectMembershipsSchema.extend({
roles: z
.object({
role: z.string()
})
.array()
}),
permissions: z.any().array() permissions: z.any().array()
}) })
}) })
@@ -1,6 +1,6 @@
--- ---
title: "Cassandra" title: "Cassandra"
description: "How to dynamically generate Cassandra database users" description: "How to dynamically generate Cassandra database users."
--- ---
The Infisical Cassandra dynamic secret allows you to generate Cassandra database credentials on demand based on configured role. The Infisical Cassandra dynamic secret allows you to generate Cassandra database credentials on demand based on configured role.
@@ -1,6 +1,6 @@
--- ---
title: "PostgreSQL" title: "PostgreSQL"
description: "How to dynamically generate PostgreSQL database users" description: "How to dynamically generate PostgreSQL database users."
--- ---
The Infisical PostgreSQL dynamic secret allows you to generate PostgreSQL database credentials on demand based on configured role. The Infisical PostgreSQL dynamic secret allows you to generate PostgreSQL database credentials on demand based on configured role.
@@ -25,23 +25,24 @@ export const UpgradeProjectAlert = ({
project, project,
transparent transparent
}: UpgradeProjectAlertProps): JSX.Element | null => { }: UpgradeProjectAlertProps): JSX.Element | null => {
const router = useRouter(); const router = useRouter();
const { membership } = useProjectPermission(); const { hasProjectRole } = useProjectPermission();
const upgradeProject = useUpgradeProject(); const upgradeProject = useUpgradeProject();
const [currentStatus, setCurrentStatus] = useState<string | null>(null); const [currentStatus, setCurrentStatus] = useState<string | null>(null);
const [isUpgrading, setIsUpgrading] = useState(false); const [isUpgrading, setIsUpgrading] = useState(false);
const isProjectAdmin = hasProjectRole("admin");
const { const {
data: projectStatus, data: projectStatus,
isLoading: statusIsLoading, isLoading: statusIsLoading,
refetch: manualProjectStatusRefetch refetch: manualProjectStatusRefetch
} = useGetUpgradeProjectStatus({ } = useGetUpgradeProjectStatus({
projectId: project.id, projectId: project.id,
enabled: membership.role === "admin" && project.version === ProjectVersion.V1, enabled: isProjectAdmin && project.version === ProjectVersion.V1,
refetchInterval: 5_000, refetchInterval: 5_000,
onSuccess: (data) => { onSuccess: (data) => {
if (membership.role !== "admin") { if (!isProjectAdmin) {
return; return;
} }
@@ -101,7 +102,7 @@ export const UpgradeProjectAlert = ({
variant="solid" variant="solid"
size="md" size="md"
isLoading={isLoading} isLoading={isLoading}
isDisabled={isLoading || membership.role !== "admin"} isDisabled={isLoading || !isProjectAdmin}
onClick={onUpgradeProject} onClick={onUpgradeProject}
> >
Upgrade Upgrade
@@ -113,13 +114,13 @@ export const UpgradeProjectAlert = ({
<div <div
className={twMerge( className={twMerge(
"mt-4 flex w-full flex-row items-center rounded-md border border-primary-600/70 bg-primary/[.07] p-4 text-base text-white", "mt-4 flex w-full flex-row items-center rounded-md border border-primary-600/70 bg-primary/[.07] p-4 text-base text-white",
membership.role !== "admin" && "opacity-80" !isProjectAdmin && "opacity-80"
)} )}
> >
<FontAwesomeIcon icon={faWarning} className="pr-6 text-6xl text-white/80" /> <FontAwesomeIcon icon={faWarning} className="pr-6 text-6xl text-white/80" />
<div className="flex w-full flex-col text-sm"> <div className="flex w-full flex-col text-sm">
<span className="mb-2 text-lg font-semibold">Upgrade your project</span> <span className="mb-2 text-lg font-semibold">Upgrade your project</span>
{membership.role === "admin" ? ( {isProjectAdmin ? (
<> <>
<p> <p>
Upgrade your project version to continue receiving the latest improvements and Upgrade your project version to continue receiving the latest improvements and
@@ -150,12 +151,12 @@ export const UpgradeProjectAlert = ({
</div> </div>
<div className="my-2"> <div className="my-2">
<Tooltip <Tooltip
className={twMerge(membership.role === "admin" && "hidden")} className={twMerge(isProjectAdmin && "hidden")}
content="You need to be an admin to upgrade the project." content="You need to be an admin to upgrade the project."
> >
<Button <Button
isLoading={isLoading} isLoading={isLoading}
isDisabled={isLoading || membership.role !== "admin"} isDisabled={isLoading || !isProjectAdmin}
onClick={onUpgradeProject} onClick={onUpgradeProject}
> >
Upgrade Upgrade
@@ -56,5 +56,7 @@ export const useProjectPermission = () => {
throw new Error("useProjectPermission to be used within <ProjectPermissionContext>"); throw new Error("useProjectPermission to be used within <ProjectPermissionContext>");
} }
return ctx; const hasProjectRole = (role: string) => ctx?.membership?.roles?.includes(role) || false;
return { ...ctx, hasProjectRole };
}; };
+8 -2
View File
@@ -106,7 +106,7 @@ const getUserProjectPermissions = async ({ workspaceId }: TGetUserProjectPermiss
const { data } = await apiRequest.get<{ const { data } = await apiRequest.get<{
data: { data: {
permissions: PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[]; permissions: PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[];
membership: TProjectMembership; membership: Omit<TProjectMembership, "roles"> & { roles: { role: string }[] };
}; };
}>(`/api/v1/workspace/${workspaceId}/permissions`, {}); }>(`/api/v1/workspace/${workspaceId}/permissions`, {});
@@ -121,6 +121,12 @@ export const useGetUserProjectPermissions = ({ workspaceId }: TGetUserProjectPer
select: (data) => { select: (data) => {
const rule = unpackRules<RawRuleOf<MongoAbility<ProjectPermissionSet>>>(data.permissions); const rule = unpackRules<RawRuleOf<MongoAbility<ProjectPermissionSet>>>(data.permissions);
const ability = createMongoAbility<ProjectPermissionSet>(rule, { conditionsMatcher }); const ability = createMongoAbility<ProjectPermissionSet>(rule, { conditionsMatcher });
return { permission: ability, membership: data.membership };
const membership = {
...data.membership,
roles: data.membership.roles.map(({ role }) => role)
};
return { permission: ability, membership };
} }
}); });
+23 -23
View File
@@ -62,7 +62,7 @@ export type TProjectMembership = {
createdAt: string; createdAt: string;
updatedAt: string; updatedAt: string;
projectId: string; projectId: string;
roleId: string; roles: string[];
}; };
export type TWorkspaceUser = { export type TWorkspaceUser = {
@@ -79,29 +79,29 @@ export type TWorkspaceUser = {
organization: string; organization: string;
roles: ( roles: (
| { | {
id: string; id: string;
role: "owner" | "admin" | "member" | "no-access" | "custom"; role: "owner" | "admin" | "member" | "no-access" | "custom";
customRoleId: string; customRoleId: string;
customRoleName: string; customRoleName: string;
customRoleSlug: string; customRoleSlug: string;
isTemporary: false; isTemporary: false;
temporaryRange: null; temporaryRange: null;
temporaryMode: null; temporaryMode: null;
temporaryAccessEndTime: null; temporaryAccessEndTime: null;
temporaryAccessStartTime: null; temporaryAccessStartTime: null;
} }
| { | {
id: string; id: string;
role: "owner" | "admin" | "member" | "no-access" | "custom"; role: "owner" | "admin" | "member" | "no-access" | "custom";
customRoleId: string; customRoleId: string;
customRoleName: string; customRoleName: string;
customRoleSlug: string; customRoleSlug: string;
isTemporary: true; isTemporary: true;
temporaryRange: string; temporaryRange: string;
temporaryMode: string; temporaryMode: string;
temporaryAccessEndTime: string; temporaryAccessEndTime: string;
temporaryAccessStartTime: string; temporaryAccessStartTime: string;
} }
)[]; )[];
status: "invited" | "accepted" | "verified" | "completed"; status: "invited" | "accepted" | "verified" | "completed";
deniedPermissions: any[]; deniedPermissions: any[];