mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: updated code by rabbit, reptile and maidul changes
This commit is contained in:
2
backend/src/@types/fastify.d.ts
vendored
2
backend/src/@types/fastify.d.ts
vendored
@@ -110,7 +110,7 @@ declare module "@fastify/request-context" {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
identityPermissionMetadata?: Record<string, unknown>; // filled by permission service
|
identityPermissionMetadata?: Record<string, unknown>; // filled by permission service
|
||||||
projectAssumeRole?: { userId: string; actorId: string; actorType: ActorType; projectId: string };
|
assumedProjectRole: { requesterId: string; actorId: string; actorType: ActorType; projectId: string };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { BadRequestError } from "@app/lib/errors";
|
|||||||
import { writeLimit } from "@app/server/config/rateLimiter";
|
import { writeLimit } from "@app/server/config/rateLimiter";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
import { requestContext } from "@fastify/request-context";
|
||||||
|
|
||||||
export const registerAssumePrivilegeRouter = async (server: FastifyZodProvider) => {
|
export const registerAssumePrivilegeRouter = async (server: FastifyZodProvider) => {
|
||||||
server.route({
|
server.route({
|
||||||
@@ -32,10 +33,10 @@ export const registerAssumePrivilegeRouter = async (server: FastifyZodProvider)
|
|||||||
handler: async (req, res) => {
|
handler: async (req, res) => {
|
||||||
if (req.auth.authMode === AuthMode.JWT) {
|
if (req.auth.authMode === AuthMode.JWT) {
|
||||||
const payload = await server.services.assumePrivileges.assumeProjectPrivileges({
|
const payload = await server.services.assumePrivileges.assumeProjectPrivileges({
|
||||||
actorType: req.body.actorType,
|
targetActorType: req.body.actorType,
|
||||||
actorId: req.body.actorId,
|
targetActorId: req.body.actorId,
|
||||||
projectId: req.params.projectId,
|
projectId: req.params.projectId,
|
||||||
projectPermission: req.permission,
|
actorPermissionDetails: req.permission,
|
||||||
tokenVersionId: req.auth.tokenVersionId
|
tokenVersionId: req.auth.tokenVersionId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -44,20 +45,22 @@ export const registerAssumePrivilegeRouter = async (server: FastifyZodProvider)
|
|||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: "/",
|
path: "/",
|
||||||
sameSite: "strict",
|
sameSite: "strict",
|
||||||
secure: appCfg.HTTPS_ENABLED
|
secure: appCfg.HTTPS_ENABLED,
|
||||||
|
maxAge: 3600 // 1 hour in seconds
|
||||||
});
|
});
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
orgId: req.permission.orgId,
|
orgId: req.permission.orgId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.PROJECT_ASSUME_PRIVILEGE,
|
type: EventType.PROJECT_ASSUME_PRIVILEGE_SESSION_START,
|
||||||
metadata: {
|
metadata: {
|
||||||
projectId: req.params.projectId,
|
projectId: req.params.projectId,
|
||||||
requesterEmail: req.auth.user.username,
|
requesterEmail: req.auth.user.username,
|
||||||
requesterId: req.auth.user.id,
|
requesterId: req.auth.user.id,
|
||||||
targetActorType: req.body.actorType,
|
targetActorType: req.body.actorType,
|
||||||
targetActorId: req.body.actorId
|
targetActorId: req.body.actorId,
|
||||||
|
duration: "1hr"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -87,24 +90,28 @@ export const registerAssumePrivilegeRouter = async (server: FastifyZodProvider)
|
|||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
handler: async (req, res) => {
|
handler: async (req, res) => {
|
||||||
if (req.auth.authMode === AuthMode.JWT) {
|
const assumePrivilege = requestContext.get("assumedProjectRole");
|
||||||
|
if (req.auth.authMode === AuthMode.JWT && assumePrivilege) {
|
||||||
const appCfg = getConfig();
|
const appCfg = getConfig();
|
||||||
void res.setCookie("infisical-project-assume-privileges", "", {
|
void res.setCookie("infisical-project-assume-privileges", "", {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: "/",
|
path: "/",
|
||||||
sameSite: "strict",
|
sameSite: "strict",
|
||||||
secure: appCfg.HTTPS_ENABLED
|
secure: appCfg.HTTPS_ENABLED,
|
||||||
|
expires: new Date(0)
|
||||||
});
|
});
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
orgId: req.permission.orgId,
|
orgId: req.permission.orgId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.PROJECT_ASSUME_PRIVILEGE_EXIT,
|
type: EventType.PROJECT_ASSUME_PRIVILEGE_SESSION_END,
|
||||||
metadata: {
|
metadata: {
|
||||||
projectId: req.params.projectId,
|
projectId: req.params.projectId,
|
||||||
requesterEmail: req.auth.user.username,
|
requesterEmail: req.auth.user.username,
|
||||||
requesterId: req.auth.user.id
|
requesterId: req.auth.user.id,
|
||||||
|
targetActorId: assumePrivilege.actorId,
|
||||||
|
targetActorType: assumePrivilege.actorType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import jwt from "jsonwebtoken";
|
|||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
import { ActionProjectType } from "@app/db/schemas";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { NotFoundError } from "@app/lib/errors";
|
import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||||
|
|
||||||
@@ -24,23 +24,24 @@ export type TAssumePrivilegeServiceFactory = ReturnType<typeof assumePrivilegeSe
|
|||||||
|
|
||||||
export const assumePrivilegeServiceFactory = ({ projectDAL, permissionService }: TAssumePrivilegeServiceFactoryDep) => {
|
export const assumePrivilegeServiceFactory = ({ projectDAL, permissionService }: TAssumePrivilegeServiceFactoryDep) => {
|
||||||
const assumeProjectPrivileges = async ({
|
const assumeProjectPrivileges = async ({
|
||||||
actorType,
|
targetActorType,
|
||||||
actorId,
|
targetActorId,
|
||||||
projectId,
|
projectId,
|
||||||
projectPermission,
|
actorPermissionDetails,
|
||||||
tokenVersionId
|
tokenVersionId
|
||||||
}: TAssumeProjectPrivilegeDTO) => {
|
}: TAssumeProjectPrivilegeDTO) => {
|
||||||
const project = await projectDAL.findById(projectId);
|
const project = await projectDAL.findById(projectId);
|
||||||
if (!project) throw new NotFoundError({ message: `Project with ID '${projectId}' not found` });
|
if (!project) throw new NotFoundError({ message: `Project with ID '${projectId}' not found` });
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor: projectPermission.type,
|
actor: actorPermissionDetails.type,
|
||||||
actorId: projectPermission.id,
|
actorId: actorPermissionDetails.id,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: projectPermission.authMethod,
|
actorAuthMethod: actorPermissionDetails.authMethod,
|
||||||
actorOrgId: projectPermission.orgId,
|
actorOrgId: actorPermissionDetails.orgId,
|
||||||
actionProjectType: ActionProjectType.Any
|
actionProjectType: ActionProjectType.Any
|
||||||
});
|
});
|
||||||
if (actorType === ActorType.USER) {
|
|
||||||
|
if (targetActorType === ActorType.USER) {
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionMemberActions.AssumePrivileges,
|
ProjectPermissionMemberActions.AssumePrivileges,
|
||||||
ProjectPermissionSub.Member
|
ProjectPermissionSub.Member
|
||||||
@@ -54,11 +55,11 @@ export const assumePrivilegeServiceFactory = ({ projectDAL, permissionService }:
|
|||||||
|
|
||||||
// check entity is part of project
|
// check entity is part of project
|
||||||
await permissionService.getProjectPermission({
|
await permissionService.getProjectPermission({
|
||||||
actor: actorType,
|
actor: targetActorType,
|
||||||
actorId,
|
actorId: targetActorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: projectPermission.authMethod,
|
actorAuthMethod: actorPermissionDetails.authMethod,
|
||||||
actorOrgId: projectPermission.orgId,
|
actorOrgId: actorPermissionDetails.orgId,
|
||||||
actionProjectType: ActionProjectType.Any
|
actionProjectType: ActionProjectType.Any
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -66,16 +67,16 @@ export const assumePrivilegeServiceFactory = ({ projectDAL, permissionService }:
|
|||||||
const assumePrivilegesToken = jwt.sign(
|
const assumePrivilegesToken = jwt.sign(
|
||||||
{
|
{
|
||||||
tokenVersionId,
|
tokenVersionId,
|
||||||
actorType,
|
actorType: targetActorType,
|
||||||
actorId,
|
actorId: targetActorId,
|
||||||
projectId,
|
projectId,
|
||||||
userId: projectPermission.id
|
requesterId: actorPermissionDetails.id
|
||||||
},
|
},
|
||||||
appCfg.AUTH_SECRET,
|
appCfg.AUTH_SECRET,
|
||||||
{ expiresIn: "1hr" }
|
{ expiresIn: "1hr" }
|
||||||
);
|
);
|
||||||
|
|
||||||
return { actorType, actorId, projectId, assumePrivilegesToken };
|
return { actorType: targetActorType, actorId: targetActorId, projectId, assumePrivilegesToken };
|
||||||
};
|
};
|
||||||
|
|
||||||
const verifyAssumePrivilegeToken = (token: string, tokenVersionId: string) => {
|
const verifyAssumePrivilegeToken = (token: string, tokenVersionId: string) => {
|
||||||
@@ -83,11 +84,13 @@ export const assumePrivilegeServiceFactory = ({ projectDAL, permissionService }:
|
|||||||
const decodedToken = jwt.verify(token, appCfg.AUTH_SECRET) as {
|
const decodedToken = jwt.verify(token, appCfg.AUTH_SECRET) as {
|
||||||
tokenVersionId: string;
|
tokenVersionId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
userId: string;
|
requesterId: string;
|
||||||
actorType: ActorType;
|
actorType: ActorType;
|
||||||
actorId: string;
|
actorId: string;
|
||||||
};
|
};
|
||||||
if (decodedToken.tokenVersionId !== tokenVersionId) return;
|
if (decodedToken.tokenVersionId !== tokenVersionId) {
|
||||||
|
throw new ForbiddenRequestError({ message: "Invalid token version" });
|
||||||
|
}
|
||||||
return decodedToken;
|
return decodedToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import { OrgServiceActor } from "@app/lib/types";
|
|||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
export type TAssumeProjectPrivilegeDTO = {
|
export type TAssumeProjectPrivilegeDTO = {
|
||||||
actorType: ActorType.USER | ActorType.IDENTITY;
|
targetActorType: ActorType.USER | ActorType.IDENTITY;
|
||||||
actorId: string;
|
targetActorId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
tokenVersionId: string;
|
tokenVersionId: string;
|
||||||
projectPermission: OrgServiceActor;
|
actorPermissionDetails: OrgServiceActor;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -318,8 +318,8 @@ export enum EventType {
|
|||||||
SECRET_ROTATION_ROTATE_SECRETS = "secret-rotation-rotate-secrets",
|
SECRET_ROTATION_ROTATE_SECRETS = "secret-rotation-rotate-secrets",
|
||||||
|
|
||||||
PROJECT_ACCESS_REQUEST = "project-access-request",
|
PROJECT_ACCESS_REQUEST = "project-access-request",
|
||||||
PROJECT_ASSUME_PRIVILEGE = "project-assume-privileges",
|
PROJECT_ASSUME_PRIVILEGE_SESSION_START = "project-assume-privileges-session-start",
|
||||||
PROJECT_ASSUME_PRIVILEGE_EXIT = "project-assume-privileges-exit"
|
PROJECT_ASSUME_PRIVILEGE_SESSION_END = "project-assume-privileges-session-end"
|
||||||
}
|
}
|
||||||
|
|
||||||
export const filterableSecretEvents: EventType[] = [
|
export const filterableSecretEvents: EventType[] = [
|
||||||
@@ -2428,22 +2428,25 @@ interface ProjectAccessRequestEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ProjectAssumePrivilegesEvent {
|
interface ProjectAssumePrivilegesEvent {
|
||||||
type: EventType.PROJECT_ASSUME_PRIVILEGE;
|
type: EventType.PROJECT_ASSUME_PRIVILEGE_SESSION_START;
|
||||||
metadata: {
|
metadata: {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
requesterId: string;
|
requesterId: string;
|
||||||
requesterEmail: string;
|
requesterEmail: string;
|
||||||
targetActorType: ActorType;
|
targetActorType: ActorType;
|
||||||
targetActorId: string;
|
targetActorId: string;
|
||||||
|
duration: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProjectAssumePrivilegesExitEvent {
|
interface ProjectAssumePrivilegesExitEvent {
|
||||||
type: EventType.PROJECT_ASSUME_PRIVILEGE_EXIT;
|
type: EventType.PROJECT_ASSUME_PRIVILEGE_SESSION_END;
|
||||||
metadata: {
|
metadata: {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
requesterId: string;
|
requesterId: string;
|
||||||
requesterEmail: string;
|
requesterEmail: string;
|
||||||
|
targetActorType: ActorType;
|
||||||
|
targetActorId: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -560,15 +560,15 @@ export const permissionServiceFactory = ({
|
|||||||
}: TGetProjectPermissionArg): Promise<TProjectPermissionRT<T>> => {
|
}: TGetProjectPermissionArg): Promise<TProjectPermissionRT<T>> => {
|
||||||
let actor = inputActor;
|
let actor = inputActor;
|
||||||
let actorId = inputActorId;
|
let actorId = inputActorId;
|
||||||
const projectAssumeRole = requestContext.get("projectAssumeRole");
|
const assumedProjectRole = requestContext.get("assumedProjectRole");
|
||||||
if (
|
if (
|
||||||
projectAssumeRole &&
|
assumedProjectRole &&
|
||||||
actor === ActorType.USER &&
|
actor === ActorType.USER &&
|
||||||
actorId === projectAssumeRole.userId &&
|
actorId === assumedProjectRole.requesterId &&
|
||||||
projectId === projectAssumeRole.projectId
|
projectId === assumedProjectRole.projectId
|
||||||
) {
|
) {
|
||||||
actor = projectAssumeRole.actorType;
|
actor = assumedProjectRole.actorType;
|
||||||
actorId = projectAssumeRole.actorId;
|
actorId = assumedProjectRole.actorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (actor) {
|
switch (actor) {
|
||||||
|
|||||||
@@ -4,16 +4,21 @@ import fp from "fastify-plugin";
|
|||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
export const injectAssumePrivilege = fp(async (server: FastifyZodProvider) => {
|
export const injectAssumePrivilege = fp(async (server: FastifyZodProvider) => {
|
||||||
server.addHook("onRequest", async (req) => {
|
server.addHook("onRequest", async (req, res) => {
|
||||||
const assumeRoleCookie = req.cookies["infisical-project-assume-privileges"];
|
const assumeRoleCookie = req.cookies["infisical-project-assume-privileges"];
|
||||||
if (req?.auth?.authMode === AuthMode.JWT && assumeRoleCookie) {
|
try {
|
||||||
const decodedToken = server.services.assumePrivileges.verifyAssumePrivilegeToken(
|
if (req?.auth?.authMode === AuthMode.JWT && assumeRoleCookie) {
|
||||||
assumeRoleCookie,
|
const decodedToken = server.services.assumePrivileges.verifyAssumePrivilegeToken(
|
||||||
req.auth.tokenVersionId
|
assumeRoleCookie,
|
||||||
);
|
req.auth.tokenVersionId
|
||||||
if (decodedToken) {
|
);
|
||||||
requestContext.set("projectAssumeRole", decodedToken);
|
if (decodedToken) {
|
||||||
|
requestContext.set("assumedProjectRole", decodedToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
req.log.error({ error }, "Failed to verify assume privilege token");
|
||||||
|
void res.clearCookie("infisical-project-assume-privileges");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => {
|
|||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: "/",
|
path: "/",
|
||||||
sameSite: "strict",
|
sameSite: "strict",
|
||||||
secure: appCfg.HTTPS_ENABLED
|
secure: appCfg.HTTPS_ENABLED,
|
||||||
|
maxAge: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
return { message: "Successfully logged out" };
|
return { message: "Successfully logged out" };
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
|
|||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: "/",
|
path: "/",
|
||||||
sameSite: "strict",
|
sameSite: "strict",
|
||||||
secure: cfg.HTTPS_ENABLED
|
secure: cfg.HTTPS_ENABLED,
|
||||||
|
maxAge: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
return { token: tokens.access, isMfaEnabled: false };
|
return { token: tokens.access, isMfaEnabled: false };
|
||||||
@@ -142,7 +143,8 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
|
|||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: "/",
|
path: "/",
|
||||||
sameSite: "strict",
|
sameSite: "strict",
|
||||||
secure: appCfg.HTTPS_ENABLED
|
secure: appCfg.HTTPS_ENABLED,
|
||||||
|
maxAge: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -238,21 +238,23 @@ export const projectRoleServiceFactory = ({
|
|||||||
// just to satisfy ts
|
// just to satisfy ts
|
||||||
if (!("roles" in membership)) throw new BadRequestError({ message: "Service token not allowed" });
|
if (!("roles" in membership)) throw new BadRequestError({ message: "Service token not allowed" });
|
||||||
|
|
||||||
const projectAssumeRole = requestContext.get("projectAssumeRole");
|
const assumedProjectRole = requestContext.get("assumedProjectRole");
|
||||||
const isImpersonating = projectAssumeRole?.projectId === projectId;
|
const isImpersonating = assumedProjectRole?.projectId === projectId;
|
||||||
const impersonation = isImpersonating
|
const impersonation = isImpersonating
|
||||||
? {
|
? {
|
||||||
actorId: projectAssumeRole?.actorId,
|
actorId: assumedProjectRole?.actorId,
|
||||||
actorType: projectAssumeRole?.actorType,
|
actorType: assumedProjectRole?.actorType,
|
||||||
actorName: "",
|
actorName: "",
|
||||||
actorEmail: ""
|
actorEmail: ""
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
if (impersonation?.actorType === ActorType.IDENTITY) {
|
if (impersonation?.actorType === ActorType.IDENTITY) {
|
||||||
const identityDetails = await identityDAL.findById(impersonation.actorId);
|
const identityDetails = await identityDAL.findById(impersonation.actorId);
|
||||||
|
if (!identityDetails) throw new NotFoundError({ message: `Identity with ID ${impersonation.actorId} not found` });
|
||||||
impersonation.actorName = identityDetails.name;
|
impersonation.actorName = identityDetails.name;
|
||||||
} else if (impersonation?.actorType === ActorType.USER) {
|
} else if (impersonation?.actorType === ActorType.USER) {
|
||||||
const userDetails = await userDAL.findById(impersonation?.actorId);
|
const userDetails = await userDAL.findById(impersonation?.actorId);
|
||||||
|
if (!userDetails) throw new NotFoundError({ message: `User with ID ${impersonation.actorId} not found` });
|
||||||
impersonation.actorName = `${userDetails?.firstName} ${userDetails?.lastName || ""}`;
|
impersonation.actorName = `${userDetails?.firstName} ${userDetails?.lastName || ""}`;
|
||||||
impersonation.actorEmail = userDetails?.email || "";
|
impersonation.actorEmail = userDetails?.email || "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ export const ConfirmActionModal = ({
|
|||||||
setIsLoading.on();
|
setIsLoading.on();
|
||||||
try {
|
try {
|
||||||
await onConfirmed();
|
await onConfirmed();
|
||||||
} catch {
|
|
||||||
setIsLoading.off();
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading.off();
|
setIsLoading.off();
|
||||||
}
|
}
|
||||||
@@ -77,7 +75,7 @@ export const ConfirmActionModal = ({
|
|||||||
<Button variant="plain" colorSchema="secondary" onClick={onClose}>
|
<Button variant="plain" colorSchema="secondary" onClick={onClose}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</ModalClose>{" "}
|
</ModalClose>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ const Page = () => {
|
|||||||
|
|
||||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||||
"deleteIdentity",
|
"deleteIdentity",
|
||||||
"upgradePlan",
|
|
||||||
"assumePrivileges"
|
"assumePrivileges"
|
||||||
] as const);
|
] as const);
|
||||||
const assumePrivileges = useAssumeProjectPrivileges();
|
const assumePrivileges = useAssumeProjectPrivileges();
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ export const Page = () => {
|
|||||||
variant="outline_bg"
|
variant="outline_bg"
|
||||||
size="xs"
|
size="xs"
|
||||||
isDisabled={!isAllowed}
|
isDisabled={!isAllowed}
|
||||||
isLoading={isRemovingUserFromWorkspace}
|
isLoading={assumePrivileges.isPending}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handlePopUpOpen("assumePrivileges", { userId: membershipDetails?.user?.id })
|
handlePopUpOpen("assumePrivileges", { userId: membershipDetails?.user?.id })
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user