mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 17:27:16 +00:00
feat: completed all nit changes in review
This commit is contained in:
@@ -20,7 +20,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
|
|||||||
rateLimit: writeLimit
|
rateLimit: writeLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
description: "Create an additional privilege for identity.",
|
description: "Add an additional privilege for identity.",
|
||||||
security: [
|
security: [
|
||||||
{
|
{
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
@@ -91,7 +91,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
|
|||||||
rateLimit: writeLimit
|
rateLimit: writeLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
description: "Update a specific privilege of an identity.",
|
description: "Update a specific identity privilege.",
|
||||||
security: [
|
security: [
|
||||||
{
|
{
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
@@ -167,7 +167,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
|
|||||||
rateLimit: writeLimit
|
rateLimit: writeLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
description: "Delete a specific privilege of an identity.",
|
description: "Delete the specified identity privilege.",
|
||||||
security: [
|
security: [
|
||||||
{
|
{
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
@@ -202,7 +202,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
|
|||||||
rateLimit: readLimit
|
rateLimit: readLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
description: "Retrieve details of a specific privilege by privilege id.",
|
description: "Retrieve details of a specific privilege by id.",
|
||||||
security: [
|
security: [
|
||||||
{
|
{
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
@@ -237,7 +237,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
|
|||||||
rateLimit: readLimit
|
rateLimit: readLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
description: "Retrieve details of a specific privilege by privilege slug.",
|
description: "Retrieve details of a specific privilege by slug.",
|
||||||
security: [
|
security: [
|
||||||
{
|
{
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
@@ -277,7 +277,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
|
|||||||
rateLimit: readLimit
|
rateLimit: readLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
description: "List of a specific privilege of an identity in a project.",
|
description: "List privileges for the specified identity by project.",
|
||||||
security: [
|
security: [
|
||||||
{
|
{
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
|
|||||||
+6
-6
@@ -76,7 +76,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
slug,
|
slug,
|
||||||
projectMembershipId: identityProjectMembership.id
|
projectMembershipId: identityProjectMembership.id
|
||||||
});
|
});
|
||||||
if (existingSlug) throw new BadRequestError({ message: "Additional privilege of provided slug exist" });
|
if (existingSlug) throw new BadRequestError({ message: "Additional privilege with provided slug already exists" });
|
||||||
|
|
||||||
if (!dto.isTemporary) {
|
if (!dto.isTemporary) {
|
||||||
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.create({
|
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.create({
|
||||||
@@ -117,7 +117,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorAuthMethod
|
actorAuthMethod
|
||||||
}: TUpdateIdentityPrivilegeByIdDTO) => {
|
}: TUpdateIdentityPrivilegeByIdDTO) => {
|
||||||
const identityPrivilege = await identityProjectAdditionalPrivilegeDAL.findById(id);
|
const identityPrivilege = await identityProjectAdditionalPrivilegeDAL.findById(id);
|
||||||
if (!identityPrivilege) throw new NotFoundError({ message: "Identity additional privilege not found" });
|
if (!identityPrivilege) throw new NotFoundError({ message: `Identity privilege with ${id} not found` });
|
||||||
|
|
||||||
const identityProjectMembership = await identityProjectDAL.findOne({ id: identityPrivilege.projectMembershipId });
|
const identityProjectMembership = await identityProjectDAL.findOne({ id: identityPrivilege.projectMembershipId });
|
||||||
if (!identityProjectMembership)
|
if (!identityProjectMembership)
|
||||||
@@ -150,7 +150,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
projectMembershipId: identityProjectMembership.id
|
projectMembershipId: identityProjectMembership.id
|
||||||
});
|
});
|
||||||
if (existingSlug && existingSlug.id !== identityPrivilege.id)
|
if (existingSlug && existingSlug.id !== identityPrivilege.id)
|
||||||
throw new BadRequestError({ message: "Additional privilege of provided slug exist" });
|
throw new BadRequestError({ message: "Additional privilege with provided slug already exists" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const isTemporary = typeof data?.isTemporary !== "undefined" ? data.isTemporary : identityPrivilege.isTemporary;
|
const isTemporary = typeof data?.isTemporary !== "undefined" ? data.isTemporary : identityPrivilege.isTemporary;
|
||||||
@@ -189,7 +189,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
|
|
||||||
const deleteById = async ({ actorId, id, actor, actorOrgId, actorAuthMethod }: TDeleteIdentityPrivilegeByIdDTO) => {
|
const deleteById = async ({ actorId, id, actor, actorOrgId, actorAuthMethod }: TDeleteIdentityPrivilegeByIdDTO) => {
|
||||||
const identityPrivilege = await identityProjectAdditionalPrivilegeDAL.findById(id);
|
const identityPrivilege = await identityProjectAdditionalPrivilegeDAL.findById(id);
|
||||||
if (!identityPrivilege) throw new NotFoundError({ message: "Identity additional privilege not found" });
|
if (!identityPrivilege) throw new NotFoundError({ message: `Identity privilege with ${id} not found` });
|
||||||
|
|
||||||
const identityProjectMembership = await identityProjectDAL.findOne({ id: identityPrivilege.projectMembershipId });
|
const identityProjectMembership = await identityProjectDAL.findOne({ id: identityPrivilege.projectMembershipId });
|
||||||
if (!identityProjectMembership)
|
if (!identityProjectMembership)
|
||||||
@@ -231,7 +231,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorAuthMethod
|
actorAuthMethod
|
||||||
}: TGetIdentityPrivilegeDetailsByIdDTO) => {
|
}: TGetIdentityPrivilegeDetailsByIdDTO) => {
|
||||||
const identityPrivilege = await identityProjectAdditionalPrivilegeDAL.findById(id);
|
const identityPrivilege = await identityProjectAdditionalPrivilegeDAL.findById(id);
|
||||||
if (!identityPrivilege) throw new NotFoundError({ message: "Identity additional privilege not found" });
|
if (!identityPrivilege) throw new NotFoundError({ message: `Identity privilege with ${id} not found` });
|
||||||
|
|
||||||
const identityProjectMembership = await identityProjectDAL.findOne({ id: identityPrivilege.projectMembershipId });
|
const identityProjectMembership = await identityProjectDAL.findOne({ id: identityPrivilege.projectMembershipId });
|
||||||
if (!identityProjectMembership)
|
if (!identityProjectMembership)
|
||||||
@@ -264,7 +264,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorAuthMethod
|
actorAuthMethod
|
||||||
}: TGetIdentityPrivilegeDetailsBySlugDTO) => {
|
}: TGetIdentityPrivilegeDetailsBySlugDTO) => {
|
||||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
if (!project) throw new NotFoundError({ message: "Project not found" });
|
if (!project) throw new NotFoundError({ message: `Project with slug ${slug} not found` });
|
||||||
const projectId = project.id;
|
const projectId = project.id;
|
||||||
|
|
||||||
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
|
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
|
||||||
|
|||||||
+31
-8
@@ -2,8 +2,10 @@ import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability";
|
|||||||
import { PackRule, unpackRules } from "@casl/ability/extra";
|
import { PackRule, unpackRules } from "@casl/ability/extra";
|
||||||
import ms from "ms";
|
import ms from "ms";
|
||||||
|
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||||
|
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission";
|
import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission";
|
||||||
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
|
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
|
||||||
|
|
||||||
import { TPermissionServiceFactory } from "../permission/permission-service";
|
import { TPermissionServiceFactory } from "../permission/permission-service";
|
||||||
@@ -50,7 +52,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
}: TCreateUserPrivilegeDTO) => {
|
}: TCreateUserPrivilegeDTO) => {
|
||||||
const projectMembership = await projectMembershipDAL.findById(projectMembershipId);
|
const projectMembership = await projectMembershipDAL.findById(projectMembershipId);
|
||||||
if (!projectMembership)
|
if (!projectMembership)
|
||||||
throw new NotFoundError({ message: `Project membership with ID '${projectMembershipId}' not found` });
|
throw new NotFoundError({ message: `Project membership with ID ${projectMembershipId} found` });
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
@@ -60,13 +62,24 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
|
||||||
|
const { permission: entityPermission } = await permissionService.getProjectPermission(
|
||||||
|
ActorType.USER,
|
||||||
|
projectMembership.userId,
|
||||||
|
projectMembership.projectId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, entityPermission);
|
||||||
|
if (!hasRequiredPriviledges)
|
||||||
|
throw new ForbiddenRequestError({ message: "Failed to update more privileged identity" });
|
||||||
|
|
||||||
const existingSlug = await projectUserAdditionalPrivilegeDAL.findOne({
|
const existingSlug = await projectUserAdditionalPrivilegeDAL.findOne({
|
||||||
slug,
|
slug,
|
||||||
projectId: projectMembership.projectId,
|
projectId: projectMembership.projectId,
|
||||||
userId: projectMembership.userId
|
userId: projectMembership.userId
|
||||||
});
|
});
|
||||||
if (existingSlug) throw new BadRequestError({ message: "Additional privilege of provided slug exist" });
|
if (existingSlug)
|
||||||
|
throw new BadRequestError({ message: `Additional privilege with provided slug ${slug} already exists` });
|
||||||
|
|
||||||
if (!dto.isTemporary) {
|
if (!dto.isTemporary) {
|
||||||
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.create({
|
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.create({
|
||||||
@@ -109,7 +122,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
}: TUpdateUserPrivilegeDTO) => {
|
}: TUpdateUserPrivilegeDTO) => {
|
||||||
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
|
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
|
||||||
if (!userPrivilege)
|
if (!userPrivilege)
|
||||||
throw new NotFoundError({ message: `User additional privilege with ID '${privilegeId}' not found` });
|
throw new NotFoundError({ message: `User additional privilege with ID ${privilegeId} not found` });
|
||||||
|
|
||||||
const projectMembership = await projectMembershipDAL.findOne({
|
const projectMembership = await projectMembershipDAL.findOne({
|
||||||
userId: userPrivilege.userId,
|
userId: userPrivilege.userId,
|
||||||
@@ -129,6 +142,16 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
|
||||||
|
const { permission: entityPermission } = await permissionService.getProjectPermission(
|
||||||
|
ActorType.USER,
|
||||||
|
projectMembership.userId,
|
||||||
|
projectMembership.projectId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, entityPermission);
|
||||||
|
if (!hasRequiredPriviledges)
|
||||||
|
throw new ForbiddenRequestError({ message: "Failed to update more privileged identity" });
|
||||||
|
|
||||||
if (dto?.slug) {
|
if (dto?.slug) {
|
||||||
const existingSlug = await projectUserAdditionalPrivilegeDAL.findOne({
|
const existingSlug = await projectUserAdditionalPrivilegeDAL.findOne({
|
||||||
@@ -137,7 +160,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
projectId: projectMembership.projectId
|
projectId: projectMembership.projectId
|
||||||
});
|
});
|
||||||
if (existingSlug && existingSlug.id !== userPrivilege.id)
|
if (existingSlug && existingSlug.id !== userPrivilege.id)
|
||||||
throw new BadRequestError({ message: "Additional privilege of provided slug exist" });
|
throw new BadRequestError({ message: `Additional privilege with provided slug ${dto.slug} already exists` });
|
||||||
}
|
}
|
||||||
|
|
||||||
const isTemporary = typeof dto?.isTemporary !== "undefined" ? dto.isTemporary : userPrivilege.isTemporary;
|
const isTemporary = typeof dto?.isTemporary !== "undefined" ? dto.isTemporary : userPrivilege.isTemporary;
|
||||||
@@ -178,7 +201,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
const deleteById = async ({ actorId, actor, actorOrgId, actorAuthMethod, privilegeId }: TDeleteUserPrivilegeDTO) => {
|
const deleteById = async ({ actorId, actor, actorOrgId, actorAuthMethod, privilegeId }: TDeleteUserPrivilegeDTO) => {
|
||||||
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
|
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
|
||||||
if (!userPrivilege)
|
if (!userPrivilege)
|
||||||
throw new NotFoundError({ message: `User additional privilege with ID '${privilegeId}' not found` });
|
throw new NotFoundError({ message: `User additional privilege with ID ${privilegeId} not found` });
|
||||||
|
|
||||||
const projectMembership = await projectMembershipDAL.findOne({
|
const projectMembership = await projectMembershipDAL.findOne({
|
||||||
userId: userPrivilege.userId,
|
userId: userPrivilege.userId,
|
||||||
@@ -214,7 +237,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
}: TGetUserPrivilegeDetailsDTO) => {
|
}: TGetUserPrivilegeDetailsDTO) => {
|
||||||
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
|
const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId);
|
||||||
if (!userPrivilege)
|
if (!userPrivilege)
|
||||||
throw new NotFoundError({ message: `User additional privilege with ID '${privilegeId}' not found` });
|
throw new NotFoundError({ message: `User additional privilege with ID ${privilegeId} not found` });
|
||||||
|
|
||||||
const projectMembership = await projectMembershipDAL.findOne({
|
const projectMembership = await projectMembershipDAL.findOne({
|
||||||
userId: userPrivilege.userId,
|
userId: userPrivilege.userId,
|
||||||
@@ -249,7 +272,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
}: TListUserPrivilegesDTO) => {
|
}: TListUserPrivilegesDTO) => {
|
||||||
const projectMembership = await projectMembershipDAL.findById(projectMembershipId);
|
const projectMembership = await projectMembershipDAL.findById(projectMembershipId);
|
||||||
if (!projectMembership)
|
if (!projectMembership)
|
||||||
throw new NotFoundError({ message: `Project membership with ID '${projectMembershipId}' not found` });
|
throw new NotFoundError({ message: `Project membership with ID ${projectMembershipId} not found` });
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
|
|||||||
@@ -974,27 +974,27 @@ export const PROJECT_USER_ADDITIONAL_PRIVILEGE = {
|
|||||||
|
|
||||||
export const IDENTITY_ADDITIONAL_PRIVILEGE_V2 = {
|
export const IDENTITY_ADDITIONAL_PRIVILEGE_V2 = {
|
||||||
CREATE: {
|
CREATE: {
|
||||||
identityId: "The ID of the identity to create.",
|
identityId: "The ID of the identity to create the privilege for",
|
||||||
projectId: "The ID of the project of the identity in.",
|
projectId: "The ID of the project of the identity in.",
|
||||||
slug: "The slug of the privilege to create.",
|
slug: "The slug of the privilege to create.",
|
||||||
permission: "The permission for the privilege.",
|
permission: "The permission for the privilege.",
|
||||||
isTemporary: "Whether the privilege is temporary.",
|
isTemporary: "Whether the privilege is temporary or permanent.",
|
||||||
temporaryMode: "Type of temporary access given. Types: relative",
|
temporaryMode: "Type of temporary access given. Types: relative",
|
||||||
temporaryRange: "TTL for the temporay time. Eg: 1m, 1h, 1d",
|
temporaryRange: "The TTL for the temporary access given",
|
||||||
temporaryAccessStartTime: "ISO time for which temporary access should begin."
|
temporaryAccessStartTime: "The start time in ISO format when the temporary access should begin."
|
||||||
},
|
},
|
||||||
UPDATE: {
|
UPDATE: {
|
||||||
id: "The id of the privilege of the identity.",
|
id: "The ID of the identity privilege.",
|
||||||
identityId: "The ID of the identity to update.",
|
identityId: "The ID of the identity to update.",
|
||||||
slug: "The slug of the privilege to update.",
|
slug: "The slug of the privilege to update.",
|
||||||
privilegePermission: "The permission for the privilege.",
|
privilegePermission: "The permission for the privilege.",
|
||||||
isTemporary: "Whether the privilege is temporary.",
|
isTemporary: "Whether the privilege is temporary.",
|
||||||
temporaryMode: "Type of temporary access given. Types: relative",
|
temporaryMode: "Type of temporary access given. Types: relative",
|
||||||
temporaryRange: "TTL for the temporay time. Eg: 1m, 1h, 1d",
|
temporaryRange: "The TTL for the temporary access given",
|
||||||
temporaryAccessStartTime: "ISO time for which temporary access should begin."
|
temporaryAccessStartTime: "The start time in ISO format when the temporary access should begin."
|
||||||
},
|
},
|
||||||
DELETE: {
|
DELETE: {
|
||||||
id: "the id of the privilege of the identity.",
|
id: "The ID of the identity privilege.",
|
||||||
identityId: "The ID of the identity to delete.",
|
identityId: "The ID of the identity to delete.",
|
||||||
slug: "The slug of the privilege to delete."
|
slug: "The slug of the privilege to delete."
|
||||||
},
|
},
|
||||||
@@ -1004,10 +1004,10 @@ export const IDENTITY_ADDITIONAL_PRIVILEGE_V2 = {
|
|||||||
slug: "The slug of the privilege."
|
slug: "The slug of the privilege."
|
||||||
},
|
},
|
||||||
GET_BY_ID: {
|
GET_BY_ID: {
|
||||||
id: "The id of the privilege of the identity."
|
id: "The ID of the identity privilege."
|
||||||
},
|
},
|
||||||
LIST: {
|
LIST: {
|
||||||
projectId: "The ID of the project of the identity in.",
|
projectId: "The ID of the project that the identity is in.",
|
||||||
identityId: "The ID of the identity to list."
|
identityId: "The ID of the identity to list."
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const membership = await server.services.projectMembership.getProjectMembershipById({
|
const membership = await server.services.projectMembership.getProjectMembershipById({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const glob: JsInterpreter<FieldCondition<string>> = (node, object, context) => {
|
|||||||
const conditionsMatcher = buildMongoQueryMatcher({ $glob }, { glob });
|
const conditionsMatcher = buildMongoQueryMatcher({ $glob }, { glob });
|
||||||
|
|
||||||
export const roleQueryKeys = {
|
export const roleQueryKeys = {
|
||||||
getProjectRoles: (projectId: string) => ["roles", { projectSlug: projectId }] as const,
|
getProjectRoles: (projectId: string) => ["roles", { projectId }] as const,
|
||||||
getProjectRoleBySlug: (projectId: string, roleSlug: string) =>
|
getProjectRoleBySlug: (projectId: string, roleSlug: string) =>
|
||||||
["roles", { projectId, roleSlug }] as const,
|
["roles", { projectId, roleSlug }] as const,
|
||||||
getOrgRoles: (orgId: string) => ["org-roles", { orgId }] as const,
|
getOrgRoles: (orgId: string) => ["org-roles", { orgId }] as const,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
|
||||||
|
|||||||
@@ -56,10 +56,10 @@ export const IdentityDetailsPage = withProjectPermission(
|
|||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div>
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Edit}
|
I={ProjectPermissionActions.Delete}
|
||||||
a={ProjectPermissionSub.Identity}
|
a={ProjectPermissionSub.Identity}
|
||||||
renderTooltip
|
renderTooltip
|
||||||
allowedLabel="Edit role"
|
allowedLabel="Remove from project"
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
+1
-3
@@ -206,9 +206,7 @@ export const IdentityProjectAdditionalPrivilegeModifySection = ({
|
|||||||
<IconButton ariaLabel="go-back" variant="plain" onClick={onGoBack}>
|
<IconButton ariaLabel="go-back" variant="plain" onClick={onGoBack}>
|
||||||
<FontAwesomeIcon icon={faChevronLeft} />
|
<FontAwesomeIcon icon={faChevronLeft} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<h3 className="text-lg font-semibold text-mineshaft-100">
|
<h3 className="text-lg font-semibold text-mineshaft-100">Edit Additional Privilege</h3>
|
||||||
Modify Additional Privilege
|
|
||||||
</h3>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex items-center space-x-4">
|
||||||
{isDirty && (
|
{isDirty && (
|
||||||
|
|||||||
+2
-2
@@ -98,7 +98,7 @@ export const IdentityProjectAdditionalPrivilegeSection = ({ identityMembershipDe
|
|||||||
>
|
>
|
||||||
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
||||||
<h3 className="text-lg font-semibold text-mineshaft-100">
|
<h3 className="text-lg font-semibold text-mineshaft-100">
|
||||||
Project Additional Privilege
|
Project Additional Privileges
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
@@ -174,7 +174,7 @@ export const IdentityProjectAdditionalPrivilegeSection = ({ identityMembershipDe
|
|||||||
}}
|
}}
|
||||||
onClick={() => handlePopUpOpen("modifyPrivilege", privilegeDetails)}
|
onClick={() => handlePopUpOpen("modifyPrivilege", privilegeDetails)}
|
||||||
>
|
>
|
||||||
<Td className="capitalize">{privilegeDetails.slug}</Td>
|
<Td>{privilegeDetails.slug}</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<Tooltip asChild={false} content={toolTipText}>
|
<Tooltip asChild={false} content={toolTipText}>
|
||||||
<Tag
|
<Tag
|
||||||
|
|||||||
+1
-1
@@ -72,7 +72,7 @@ export const IdentityRoleDetailsSection = ({
|
|||||||
I={ProjectPermissionActions.Edit}
|
I={ProjectPermissionActions.Edit}
|
||||||
a={ProjectPermissionSub.Identity}
|
a={ProjectPermissionSub.Identity}
|
||||||
renderTooltip
|
renderTooltip
|
||||||
allowedLabel="Edit role"
|
allowedLabel="Edit Role(s)"
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
@@ -54,10 +54,10 @@ export const MemberDetailsPage = withProjectPermission(
|
|||||||
<h3 className="text-xl font-semibold text-mineshaft-100">Project User Access</h3>
|
<h3 className="text-xl font-semibold text-mineshaft-100">Project User Access</h3>
|
||||||
<div>
|
<div>
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Edit}
|
I={ProjectPermissionActions.Delete}
|
||||||
a={ProjectPermissionSub.Member}
|
a={ProjectPermissionSub.Member}
|
||||||
renderTooltip
|
renderTooltip
|
||||||
allowedLabel="Edit role"
|
allowedLabel="Remove from project"
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
+5
-4
@@ -1,6 +1,6 @@
|
|||||||
import { faFolder, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
|
import { faFolder, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { format,formatDistance } from "date-fns";
|
import { format, formatDistance } from "date-fns";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
@@ -19,7 +19,8 @@ import {
|
|||||||
Th,
|
Th,
|
||||||
THead,
|
THead,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Tr} from "@app/components/v2";
|
Tr
|
||||||
|
} from "@app/components/v2";
|
||||||
import {
|
import {
|
||||||
ProjectPermissionActions,
|
ProjectPermissionActions,
|
||||||
ProjectPermissionSub,
|
ProjectPermissionSub,
|
||||||
@@ -104,7 +105,7 @@ export const MemberProjectAdditionalPrivilegeSection = ({ membershipDetails }: P
|
|||||||
>
|
>
|
||||||
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
||||||
<h3 className="text-lg font-semibold text-mineshaft-100">
|
<h3 className="text-lg font-semibold text-mineshaft-100">
|
||||||
Project Additional Privilege
|
Project Additional Privileges
|
||||||
</h3>
|
</h3>
|
||||||
{userId !== membershipDetails?.user?.id &&
|
{userId !== membershipDetails?.user?.id &&
|
||||||
membershipDetails?.status !== "invited" && (
|
membershipDetails?.status !== "invited" && (
|
||||||
@@ -180,7 +181,7 @@ export const MemberProjectAdditionalPrivilegeSection = ({ membershipDetails }: P
|
|||||||
}}
|
}}
|
||||||
onClick={() => handlePopUpOpen("modifyPrivilege", privilegeDetails)}
|
onClick={() => handlePopUpOpen("modifyPrivilege", privilegeDetails)}
|
||||||
>
|
>
|
||||||
<Td className="capitalize">{privilegeDetails.slug}</Td>
|
<Td>{privilegeDetails.slug}</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<Tooltip asChild={false} content={toolTipText}>
|
<Tooltip asChild={false} content={toolTipText}>
|
||||||
<Tag
|
<Tag
|
||||||
|
|||||||
+1
-1
@@ -163,7 +163,7 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({
|
|||||||
onGoBack();
|
onGoBack();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
createNotification({ type: "error", text: "Failed to update role" });
|
createNotification({ type: "error", text: "Failed to update privilege" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -20,7 +20,8 @@ import {
|
|||||||
Th,
|
Th,
|
||||||
THead,
|
THead,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Tr} from "@app/components/v2";
|
Tr
|
||||||
|
} from "@app/components/v2";
|
||||||
import {
|
import {
|
||||||
ProjectPermissionActions,
|
ProjectPermissionActions,
|
||||||
ProjectPermissionSub,
|
ProjectPermissionSub,
|
||||||
@@ -81,7 +82,7 @@ export const MemberRoleDetailsSection = ({
|
|||||||
I={ProjectPermissionActions.Edit}
|
I={ProjectPermissionActions.Edit}
|
||||||
a={ProjectPermissionSub.Member}
|
a={ProjectPermissionSub.Member}
|
||||||
renderTooltip
|
renderTooltip
|
||||||
allowedLabel="Edit role"
|
allowedLabel="Edit role(s)"
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
+8
-5
@@ -19,16 +19,19 @@ export const IdentityRoleForm = ({ identityProjectMember, onOpenUpgradeModal }:
|
|||||||
identityProjectMember={identityProjectMember}
|
identityProjectMember={identityProjectMember}
|
||||||
onOpenUpgradeModal={onOpenUpgradeModal}
|
onOpenUpgradeModal={onOpenUpgradeModal}
|
||||||
/>
|
/>
|
||||||
<Alert className="mt-4">
|
<Alert
|
||||||
|
title="Additional privileges have been moved and now offer full permission customization."
|
||||||
|
className="mt-4 border-primary/50 bg-primary/10"
|
||||||
|
>
|
||||||
<AlertDescription>
|
<AlertDescription>
|
||||||
Additional privileges now offer full permissions and have been moved to a new screen.
|
|
||||||
<br />
|
|
||||||
<Link
|
<Link
|
||||||
href={`/project/${currentWorkspace?.id || ""}/identitiesq/${
|
href={`/project/${currentWorkspace?.id || ""}/identities/${
|
||||||
identityProjectMember?.identity?.id
|
identityProjectMember?.identity?.id
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="cursor-pointer text-primary">Click here to access them.</span>
|
<span className="cursor-pointer text-primary underline underline-offset-2">
|
||||||
|
Click here to access them now
|
||||||
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|||||||
+7
-4
@@ -15,12 +15,15 @@ export const MemberRoleForm = ({ projectMember, onOpenUpgradeModal }: Props) =>
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<MemberRbacSection projectMember={projectMember} onOpenUpgradeModal={onOpenUpgradeModal} />
|
<MemberRbacSection projectMember={projectMember} onOpenUpgradeModal={onOpenUpgradeModal} />
|
||||||
<Alert className="mt-4">
|
<Alert
|
||||||
|
title="Additional privileges have been moved and now offer full permission customization."
|
||||||
|
className="mt-4 border-primary/50 bg-primary/10"
|
||||||
|
>
|
||||||
<AlertDescription>
|
<AlertDescription>
|
||||||
Additional privileges now offer full permissions and have been moved to a new screen.
|
|
||||||
<br />
|
|
||||||
<Link href={`/project/${currentWorkspace?.id || ""}/members/${projectMember?.id}`}>
|
<Link href={`/project/${currentWorkspace?.id || ""}/members/${projectMember?.id}`}>
|
||||||
<span className="cursor-pointer text-primary">Click here to access them.</span>
|
<span className="cursor-pointer text-primary underline underline-offset-2">
|
||||||
|
Click here to access them now
|
||||||
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|||||||
Reference in New Issue
Block a user