From 4d6e12d6b2eb21e334bec5f9fc1ad30604fa3cc2 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Tue, 2 Sep 2025 12:44:02 -0700 Subject: [PATCH] improvements: address feedback --- backend/src/server/routes/v1/admin-router.ts | 2 +- .../emails/OrganizationAssignmentTemplate.tsx | 1 - .../super-admin/super-admin-service.ts | 8 ++-- frontend/src/hooks/api/admin/types.ts | 4 +- frontend/src/hooks/api/organization/types.ts | 5 +++ .../components/NavBar/Navbar.tsx | 8 +++- .../components/AddServerAdminModal.tsx | 14 +++--- .../components/ServerAdminsTable.tsx | 6 +-- .../components/OrganizationsTable.tsx | 45 ++++++++++--------- .../components/UserIdentitiesTable.tsx | 8 ++-- 10 files changed, 59 insertions(+), 42 deletions(-) diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index aa36a717d..1d999ba36 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -850,7 +850,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { schema: { body: z.object({ name: GenericResourceNameSchema, - inviteAdminEmails: z.string().email().array() + inviteAdminEmails: z.string().email().array().min(1) }), response: { 200: z.object({ diff --git a/backend/src/services/smtp/emails/OrganizationAssignmentTemplate.tsx b/backend/src/services/smtp/emails/OrganizationAssignmentTemplate.tsx index a73ce4040..14fb30d80 100644 --- a/backend/src/services/smtp/emails/OrganizationAssignmentTemplate.tsx +++ b/backend/src/services/smtp/emails/OrganizationAssignmentTemplate.tsx @@ -9,7 +9,6 @@ interface OrganizationAssignmentTemplateProps extends Omit; keyStore: Pick; - licenseService: Pick; + licenseService: Pick; microsoftTeamsService: Pick; invalidateCacheQueue: TInvalidateCacheQueueFactory; smtpService: Pick; @@ -811,13 +811,13 @@ export const superAdminServiceFactory = ({ } const inviteeUserId = inviteeUser?.id; - const existingEncrytionKey = await userDAL.findUserEncKeyByUserId(inviteeUserId, tx); + const existingEncryptionKey = await userDAL.findUserEncKeyByUserId(inviteeUserId, tx); // when user is missing the encrytion keys // this could happen either if user doesn't exist or user didn't find step 3 of generating the encryption keys of srp // So what we do is we generate a random secure password and then encrypt it with a random pub-private key // Then when user sign in (as login is not possible as isAccepted is false) we rencrypt the private key with the user password - if (!inviteeUser || (inviteeUser && !inviteeUser?.isAccepted && !existingEncrytionKey)) { + if (!inviteeUser || (inviteeUser && !inviteeUser?.isAccepted && !existingEncryptionKey)) { await userDAL.createUserEncryption( { userId: inviteeUserId, @@ -853,6 +853,8 @@ export const superAdminServiceFactory = ({ return { organization: org, users }; }); + await licenseService.updateSubscriptionOrgMemberCount(organization.id); + await Promise.allSettled( usersToEmail.map(async (user) => { if (!user.email) return; diff --git a/frontend/src/hooks/api/admin/types.ts b/frontend/src/hooks/api/admin/types.ts index 6e2e1b3e2..f6c2f1a23 100644 --- a/frontend/src/hooks/api/admin/types.ts +++ b/frontend/src/hooks/api/admin/types.ts @@ -1,3 +1,5 @@ +import { OrgMembershipStatus } from "@app/hooks/api/organization/types"; + import { Organization } from "../types"; export enum LoginMethod { @@ -20,7 +22,7 @@ export type OrganizationWithProjects = Organization & { lastName: string | null; }; membershipId: string; - status: string; + status: OrgMembershipStatus; role: string; roleId: string | null; }[]; diff --git a/frontend/src/hooks/api/organization/types.ts b/frontend/src/hooks/api/organization/types.ts index 71f2a8b90..e9c36fada 100644 --- a/frontend/src/hooks/api/organization/types.ts +++ b/frontend/src/hooks/api/organization/types.ts @@ -159,3 +159,8 @@ export enum OrgIdentityOrderBy { Name = "name", Role = "role" } + +export enum OrgMembershipStatus { + Invited = "invited", + Accepted = "accepted" +} diff --git a/frontend/src/layouts/OrganizationLayout/components/NavBar/Navbar.tsx b/frontend/src/layouts/OrganizationLayout/components/NavBar/Navbar.tsx index ab74e199c..218156913 100644 --- a/frontend/src/layouts/OrganizationLayout/components/NavBar/Navbar.tsx +++ b/frontend/src/layouts/OrganizationLayout/components/NavBar/Navbar.tsx @@ -192,14 +192,18 @@ export const Navbar = () => {

/

{isServerAdminPanel ? ( <> -
+
Server Console
-
+

/

{breadcrumbs ? ( + // scott: remove /admin as we show server console above ) : null} diff --git a/frontend/src/pages/admin/AccessManagementPage/components/AddServerAdminModal.tsx b/frontend/src/pages/admin/AccessManagementPage/components/AddServerAdminModal.tsx index 53e045420..aa02d40e8 100644 --- a/frontend/src/pages/admin/AccessManagementPage/components/AddServerAdminModal.tsx +++ b/frontend/src/pages/admin/AccessManagementPage/components/AddServerAdminModal.tsx @@ -89,11 +89,7 @@ const Content = ({ onClose }: ContentProps) => {
( - + { isDisabled={isSubmitting} colorSchema="secondary" > - Grant Server Admin + Grant - )} + {role === OrgMembershipRole.Admin && + status !== OrgMembershipStatus.Accepted && ( + + )} @@ -485,9 +490,9 @@ const OrganizationsPanelTable = ({ {!org.members.some( (member) => member.role === OrgMembershipRole.Admin && - member.status === "accepted" + member.status === OrgMembershipStatus.Accepted ) && ( - +
diff --git a/frontend/src/pages/admin/ResourceOverviewPage/components/UserIdentitiesTable.tsx b/frontend/src/pages/admin/ResourceOverviewPage/components/UserIdentitiesTable.tsx index 7f4ef07a7..9856ee497 100644 --- a/frontend/src/pages/admin/ResourceOverviewPage/components/UserIdentitiesTable.tsx +++ b/frontend/src/pages/admin/ResourceOverviewPage/components/UserIdentitiesTable.tsx @@ -521,14 +521,14 @@ export const UserIdentitiesTable = () => { /> handlePopUpToggle("removeUsers", isOpen)} deleteKey="confirm" onDeleteApproved={() => handleRemoveUsers()} - buttonText="Remove" + buttonText="Delete" >
- The following members will be removed: + The following users will be deleted:
    @@ -555,7 +555,7 @@ export const UserIdentitiesTable = () => { className="ml-1 mt-[0.05rem] inline-flex w-min items-center gap-1.5 whitespace-nowrap" > - Removing Yourself + Deleting Yourself