From 2717726440b6ea0b99dddb1dbbcbcf7640a7d51a Mon Sep 17 00:00:00 2001 From: DCCONSTRUCTIONS Date: Wed, 13 May 2026 01:39:05 +0300 Subject: [PATCH] =?UTF-8?q?FIX=20-=20=D0=9C=D0=95=D0=96=D0=9F=D0=A0=D0=9E?= =?UTF-8?q?=D0=95=D0=9A=D0=A2=D0=9D=D0=90=D0=AF=20=D0=9A=D0=9E=D0=9C=D0=9C?= =?UTF-8?q?=D0=A3=D0=9D=D0=98=D0=9A=D0=90=D0=A6=D0=98=D0=AF:=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C=20approval=20workspa?= =?UTF-8?q?ce-=D0=B8=D0=BD=D0=B2=D0=B0=D0=B9=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/plane/app/views/workspace/invite.py | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/plane-src/apps/api/plane/app/views/workspace/invite.py b/plane-src/apps/api/plane/app/views/workspace/invite.py index ad09c73..815ca78 100644 --- a/plane-src/apps/api/plane/app/views/workspace/invite.py +++ b/plane-src/apps/api/plane/app/views/workspace/invite.py @@ -46,6 +46,12 @@ from plane.utils.workspace_bans import is_workspace_member_currently_banned, rel from .. import BaseViewSet +NODEDC_ACCEPTABLE_WORKSPACE_INVITE_APPROVAL_STATUSES = ( + WorkspaceMemberInvite.NODEDC_APPROVAL_NOT_REQUIRED, + WorkspaceMemberInvite.NODEDC_APPROVAL_APPROVED, +) + + class WorkspaceInvitationsViewset(BaseViewSet): """Endpoint for creating, listing and deleting workspaces""" @@ -156,9 +162,17 @@ class WorkspaceInvitationsViewset(BaseViewSet): approval_response = request_nodedc_workspace_invite_approval(request, workspace, invitation) approval_request = approval_response.get("taskerInviteRequest") if isinstance(approval_response, dict) else None approval_request_id = approval_request.get("id") if isinstance(approval_request, dict) else None + approval_request_status = approval_request.get("status") if isinstance(approval_request, dict) else None + update_fields = ["updated_at"] if approval_request_id: invitation.nodedc_approval_request_id = approval_request_id - invitation.save(update_fields=["nodedc_approval_request_id", "updated_at"]) + update_fields.append("nodedc_approval_request_id") + if approval_request_status == "approved": + invitation.nodedc_approval_status = WorkspaceMemberInvite.NODEDC_APPROVAL_APPROVED + invitation.nodedc_approval_decided_at = timezone.now() + update_fields.extend(["nodedc_approval_status", "nodedc_approval_decided_at"]) + if len(update_fields) > 1: + invitation.save(update_fields=update_fields) approved_requests.append(approval_request_id) invited_user = User.objects.filter(email__iexact=invitation.email, is_bot=False).first() publish_nodedc_workspace_event_on_commit( @@ -423,7 +437,13 @@ class UserWorkspaceInvitationsViewSet(BaseViewSet): def get_queryset(self): return self.filter_queryset( - super().get_queryset().filter(email=self.request.user.email).select_related("workspace") + super() + .get_queryset() + .filter( + email=self.request.user.email, + nodedc_approval_status__in=NODEDC_ACCEPTABLE_WORKSPACE_INVITE_APPROVAL_STATUSES, + ) + .select_related("workspace") ) @invalidate_cache(path="/api/workspaces/", user=False) @@ -431,9 +451,17 @@ class UserWorkspaceInvitationsViewSet(BaseViewSet): def create(self, request): invitations = request.data.get("invitations", []) workspace_invitations = WorkspaceMemberInvite.objects.filter( - pk__in=invitations, email=request.user.email + pk__in=invitations, + email=request.user.email, + nodedc_approval_status__in=NODEDC_ACCEPTABLE_WORKSPACE_INVITE_APPROVAL_STATUSES, ).order_by("-created_at") + if len(set(invitations)) != workspace_invitations.count(): + return Response( + {"error": "NODE.DC has not approved one or more workspace invitations yet"}, + status=status.HTTP_403_FORBIDDEN, + ) + # If the user is already a member of workspace and was deactivated then activate the user accepted_notifications = [] for invitation in workspace_invitations: