fix(ui): allow Org Admin session role to resolve user emails in logs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Devin AI 2026-09-11 16:21:20 +00:00
parent bde96e3197
commit 3630642110
3 changed files with 21 additions and 5 deletions

View file

@ -235,7 +235,7 @@ describe("useInfiniteUsers", () => {
});
it("should execute query for each admin role", async () => {
const adminRoles = ["Admin", "Admin Viewer", "proxy_admin", "proxy_admin_viewer", "org_admin"];
const adminRoles = ["Admin", "Admin Viewer", "proxy_admin", "proxy_admin_viewer", "org_admin", "Org Admin"];
for (const role of adminRoles) {
vi.clearAllMocks();
@ -384,6 +384,16 @@ describe("useUserEmailLookup", () => {
expect(userListCall).not.toHaveBeenCalled();
});
it("queries for the formatted Org Admin session role", async () => {
mockUseAuthorized.mockReturnValue({ ...DEFAULT_AUTH, userRole: "Org Admin" });
vi.mocked(userListCall).mockResolvedValue(buildUserListResponse(1, 1, 1));
const { result } = renderHook(() => useUserEmailLookup(["user-1-0"]), { wrapper });
await waitFor(() => expect(result.current.isSuccess).toBe(true));
expect(result.current.data).toEqual({ "user-1-0": "user-1-0@example.com" });
});
it("does not query for a non-admin role", async () => {
mockUseAuthorized.mockReturnValue({ ...DEFAULT_AUTH, userRole: "Internal User" });

View file

@ -1,7 +1,7 @@
import { userListCall, UserInfo, UserListResponse } from "@/components/networking";
import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
import { createQueryKeys } from "../common/queryKeysFactory";
import { all_admin_roles } from "@/utils/roles";
import { canListUsers } from "@/utils/roles";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
const infiniteUsersKeys = createQueryKeys("infiniteUsers");
@ -34,7 +34,7 @@ export const useInfiniteUsers = (pageSize: number = DEFAULT_PAGE_SIZE, searchEma
}
return undefined;
},
enabled: Boolean(accessToken) && all_admin_roles.includes(userRole!),
enabled: Boolean(accessToken) && canListUsers(userRole),
});
};
@ -52,7 +52,7 @@ export const useUserEmailLookup = (userIds: readonly string[]) => {
response.users.filter((user) => Boolean(user.user_email)).map((user) => [user.user_id, user.user_email]),
);
},
enabled: Boolean(accessToken) && distinctIds.length > 0 && all_admin_roles.includes(userRole!),
enabled: Boolean(accessToken) && distinctIds.length > 0 && canListUsers(userRole),
});
};
@ -64,6 +64,6 @@ export const useUserLookup = (userId: string | null) => {
const response = await userListCall(accessToken!, [userId!], 1, 1);
return response.users.find((user) => user.user_id === userId) ?? null;
},
enabled: Boolean(accessToken) && Boolean(userId) && all_admin_roles.includes(userRole!),
enabled: Boolean(accessToken) && Boolean(userId) && canListUsers(userRole),
});
};

View file

@ -28,6 +28,12 @@ export const isAdminRole = (role: string): boolean => {
return all_admin_roles.includes(role);
};
// /user/list admits proxy admins and org admins; the session role for the latter is the formatted
// "Org Admin", which all_admin_roles does not carry
const rolesAllowedToListUsers: string[] = [...all_admin_roles, "Org Admin"];
export const canListUsers = (role: string | null): boolean => rolesAllowedToListUsers.includes(role ?? "");
export const isProxyAdminRole = (role: string): boolean => {
return role === "proxy_admin" || role === "Admin";
};